TARBALL_PATTERN := freetype-*.tar.bz2
TARBALL_TO_DIR_L := %.tar.bz2
TARBALL_TO_DIR_R := %
-PATCHES :=
+PATCHES := builds/unix/config.sub
CONFIGURE_ARGS =
-include ../common.mk
+include ../common_automake.mk
--- /dev/null
+--- builds/unix/config.sub
++++ builds/unix/config.sub
+@@ -1498,3 +1498,6 @@
+ ;;
++ -acess2)
++ os=-acess2
++ ;;
+ -aros*)
+ os=-aros
TARBALL_PATTERN := MesaLib-*.tar.bz2
TARBALL_TO_DIR_L := MesaLib-%.tar.bz2
TARBALL_TO_DIR_R := Mesa-%
-PATCHES :=
+PATCHES := bin/config.sub
CONFIGURE_ARGS = --enable-osmesa --with-osmesa-bits=8 --disable-dri --disable-glx --with-dri-drivers=swrast --without-gallium-drivers --disable-egl --enable-shared
-include ../common.mk
+include ../common_automake.mk
--- /dev/null
+--- config.sub 2013-06-17 11:39:39.670720710 +0800
++++ config.sub 2013-06-17 11:48:09.149384231 +0800
+@@ -1350,2 +1350,3 @@
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
++ | -acess2 \
+ | -aos* | -aros* \
+
TARBALL_TO_DIR_R := %
CONFIGURE_LINE = $(SDIR)/configure --cc=$(HOST)-gcc --prefix=$(PREFIX)
PATCHES :=
-NOBDIR = yes
+NOBDIR = no
-include ../common.mk
+include ../common_automake.mk
OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
OBJ += pmemmap.o
-OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o utf16.o
+OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o utf16.o debug_hooks.o
OBJ += drvutil_video.o drvutil_disk.o
OBJ += messages.o modules.o syscalls.o system.o
OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
Error_Backtrace(regs->eip, regs->ebp);
return ;
}
-
+
+ Log(" Saved = %p (SP=%p)", Thread->SavedState.EIP, Thread->SavedState.ESP);
+
tVAddr diffFromScheduler = Thread->SavedState.EIP - (tVAddr)SwitchTasks;
tVAddr diffFromClone = Thread->SavedState.EIP - (tVAddr)Proc_CloneInt;
tVAddr diffFromSpawn = Thread->SavedState.EIP - (tVAddr)NewTaskHeader;
--- /dev/null
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * debug_hooks.c
+ * - Keyboard/serial kernel debug hooks
+ */
+#include <acess.h>
+#include <debug_hooks.h>
+
+// === CODE ===
+void DebugHook_HandleInput(tDebugHook *HookHandle, size_t Length, const char *Input)
+{
+ switch(*Input)
+ {
+ case '0' ... '9':
+ HookHandle->Value *= 10;
+ HookHandle->Value += *Input - '0';
+ break;
+ // Instruction Tracing
+ case 't':
+ Log("Toggle instruction tracing on %i\n", HookHandle->Value);
+ Threads_ToggleTrace( HookHandle->Value );
+ HookHandle->Value = 0;
+ break;
+
+ // Thread List Dump
+ case 'p': Threads_Dump(); return;
+ // Heap Statistics
+ case 'h': Heap_Stats(); return;
+ // PMem Statistics
+ case 'm': MM_DumpStatistics(); return;
+ // Dump Structure
+ case 's': return;
+
+ // Validate structures
+ //case 'v':
+ // Validate_VirtualMemoryUsage();
+ // return;
+ }
+}
+
#include <drv_pty.h>
#include <debug_hooks.h>
+extern void Validate_VirtualMemoryUsage(void);
+
// === TYPES ===
struct sSerialPort
{
return ;
if( Port == gSerial_KernelDebugPort )
{
+ static tDebugHook info;
static int serial_debug_mode = 0;
// Kernel serial debug hooks.
- if( serial_debug_mode )
+ if( serial_debug_mode == 2 )
+ {
+ // Leave latched mode
+ if( Ch == '.' )
+ serial_debug_mode = 0;
+ else
+ DebugHook_HandleInput(&info, 1, &Ch);
+ return ;
+ }
+ else if( serial_debug_mode )
{
- switch(Ch)
- {
- case 'p':
- Threads_Dump();
- break;
- case 'h':
- Heap_Dump();
- break;
- case 'X'-'A'+1:
+ if( Ch == 'X'-'A'+1 ) {
PTY_SendInput(Port->PTY, &Ch, 1);
- break;
+ serial_debug_mode = 0;
+ }
+ else if( Ch == '~' ) {
+ // Enter latched mode
+ serial_debug_mode = 2;
+ }
+ else {
+ DebugHook_HandleInput(&info, 1, &Ch);
+ serial_debug_mode = 0;
}
- serial_debug_mode = 0;
return ;
}
else if( Ch == 'X'-'A'+1 )
* drv/vterm_termbuf.c
* - Virtual Terminal - Terminal buffer manipulation
*/
-#define DEBUG 1
+#define DEBUG 0
#define DEBUG_CHECKHEAP 0
#include "vterm.h"
*/
#include <stddef.h>
+#include <stdbool.h>
#include <arch.h>
#ifndef HALT_CPU
typedef Sint64 tTimestamp; //!< Timestamp (miliseconds since 00:00 1 Jan 1970)
typedef Sint64 tTime; //!< Same again
typedef struct sShortSpinlock tShortSpinlock; //!< Opaque (kinda) spinlock
-typedef int bool; //!< Boolean type
typedef Uint64 off_t; //!< VFS Offset
typedef struct { char _[PAGE_SIZE];} tPage; // Representation of a page for pointer arithmatic
#ifndef _DEBUG_HOOKS_H_
#define _DEBUG_HOOKS_H_
+
+typedef struct sDebugHook {
+ //tDebugHookOutput Output;
+ Uint Value;
+ // TODO: Console support?
+} tDebugHook;
+
+extern void DebugHook_HandleInput(tDebugHook *HookHandle, size_t Length, const char *Input);
+
extern void Heap_Dump(void);
extern void Threads_Dump(void);
extern void Threads_ToggleTrace(int TID);
*/
extern void Time_RemoveTimer(tTimer *Timer);
+/**
+ * Schedule a THREAD_EVENT_TIMER to fire in \a Delay milliseconds
+ */
+extern void Time_ScheduleEvent(int Delay);
+
/**
* \brief Wait for a period of milliseconds
*/
void *Head;
void *Tail;
struct sThread *Sleeper;
+ struct sThread *SleepTail;
};
extern void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset);
}
*ListTail = us;
}
- else {
+ else if( ListHead ) {
+ us->Next = *ListHead;
*ListHead = us;
}
+ else {
+ // Nothing
+ }
//if( Proc_ThreadSync(us) )
// return ;
LOG("%p deallocated %p", __builtin_return_address(0), Timer);
}
+void Time_ScheduleEvent(int Delay)
+{
+ tTimer *t = &Proc_GetCurThread()->ThreadTimer;
+ Time_RemoveTimer(t);
+ Time_InitTimer(t, NULL, NULL);
+ Time_ScheduleTimer(t, Delay);
+}
+
/**
* \fn void Time_Delay(int Delay)
* \brief Delay for a small ammount of time
void Time_Delay(int Delay)
{
LOG("(%i)", Delay);
- tTimer *t = &Proc_GetCurThread()->ThreadTimer;
- Time_InitTimer(t, NULL, NULL);
- Time_ScheduleTimer(t, Delay);
+ Threads_ClearEvent(THREAD_EVENT_TIMER);
+ Time_ScheduleEvent(Delay);
Threads_WaitEvents(THREAD_EVENT_TIMER);
}
{
Queue->Name = Name;
Queue->NextOffset = NextOfset;
+ Queue->Sleeper = NULL;
+ Queue->SleepTail = NULL;
}
void *Workqueue_GetWork(tWorkqueue *Queue)
Threads_int_Sleep(THREAD_STAT_QUEUESLEEP,
Queue, 0,
- &Queue->Sleeper, NULL, &Queue->Protector);
+ &Queue->Sleeper, &Queue->SleepTail, &Queue->Protector);
}
}
if( Queue->Sleeper )
{
- if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
- Threads_AddActive(Queue->Sleeper);
- Queue->Sleeper = NULL;
+ ASSERTC( Queue->Sleeper->Status, !=, THREAD_STAT_ACTIVE );
+ tThread *next_sleeper = Queue->Sleeper->Next;
+ Threads_AddActive(Queue->Sleeper);
+ Queue->Sleeper = next_sleeper;
+ if(!next_sleeper)
+ Queue->SleepTail = NULL;
}
SHORTREL(&Queue->Protector);
}
OBJ := main.o interface.o adapters.o
OBJ += buffer.o
-OBJ += link.o arp.o
-OBJ += ipv4.o icmp.o
+OBJ += link.o hwaddr_cache.o
+OBJ += ipv4.o icmp.o arp.o
OBJ += ipv6.o
OBJ += firewall.o routing.o
OBJ += udp.o tcp.o
#include "include/adapters_int.h" // for MAC addr
#include <semaphore.h>
#include <timers.h>
+#include "hwaddr_cache.h"
#define ARPv6 0
#define ARP_CACHE_SIZE 128
#define ARP_MAX_AGE (60*60*1000) // 1Hr
-typedef struct sARP_CacheEnt
-{
- void *Layer3Addr;
- tMacAddr L2Addr;
- Sint64 LastUpdate;
- Sint64 LastUsed;
-} tARP_CacheEnt;
-typedef struct sARP_Cache
-{
- size_t AddrSize;
- int nCacheEnts;
- tARP_CacheEnt Cache[];
-} tARP_Cache;
-
// === IMPORTS ===
extern tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
#if ARPv6
// === PROTOTYPES ===
int ARP_Initialise();
-tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address);
void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer);
// === GLOBALS ===
- int giARP_WaitingThreads;
-struct sARP_Cache4 {
- tIPv4 IP;
- tMacAddr MAC;
- Sint64 LastUpdate;
- Sint64 LastUsed;
-} *gaARP_Cache4;
- int giARP_Cache4Space;
-tMutex glARP_Cache4;
-tSemaphore gARP_Cache4Semaphore;
-#if ARPv6
-struct sARP_Cache6 {
- tIPv6 IP;
- tMacAddr MAC;
- Sint64 LastUpdate;
- Sint64 LastUsed;
-} *gaARP_Cache6;
- int giARP_Cache6Space;
-tMutex glARP_Cache6;
-#endif
// === CODE ===
-tARP_Cache *ARP_int_CreateCache(unsigned int NumCacheEntries, size_t AddrSize)
-{
- size_t len = sizeof(tARP_Cache) + NumCacheEntries * (sizeof(tARP_CacheEnt) + AddrSize);
- tARP_Cache *ret = calloc(len, 1);
-
- ret->nCacheEnts = NumCacheEntries;
- ret->AddrSize = AddrSize;
-
- char *addr_storage_pos = (void*)&ret->Cache[NumCacheEntries];
-
- for( int i = 0; i < NumCacheEntries; i ++ )
- {
- ret->Cache[i].Layer3Addr = addr_storage_pos;
- addr_storage_pos += AddrSize;
- }
-
- return ret;
-}
/**
* \fn int ARP_Initialise()
* \brief Initalise the ARP section
*/
int ARP_Initialise()
{
- gaARP_Cache4 = malloc( ARP_CACHE_SIZE * sizeof(struct sARP_Cache4) );
- memset( gaARP_Cache4, 0, ARP_CACHE_SIZE * sizeof(struct sARP_Cache4) );
- giARP_Cache4Space = ARP_CACHE_SIZE;
-
- #if ARPv6
- gaARP_Cache6 = malloc( ARP_CACHE_SIZE * sizeof(struct sARP_Cache6) );
- memset( gaARP_Cache6, 0, ARP_CACHE_SIZE * sizeof(struct sARP_Cache6) );
- giARP_Cache6Space = ARP_CACHE_SIZE;
- #endif
-
Link_RegisterType(0x0806, ARP_int_GetPacket);
- Semaphore_Init(&gARP_Cache4Semaphore, 0, 0, "ARP4", "Cache Changes");
return 1;
}
-tMacAddr ARP_Resolve(tInterface *Interface, void *Address)
-{
- switch(Interface->Type)
- {
- case AF_INET4:
- return ARP_Resolve4(Interface, *(tIPv4*)Address);
-// case AF_INET6:
-// ret = ARP_int_CacheLookup(Interface, 16, Address);
-// if(ret == cMAC_ZERO) {
-// // TODO: Send ICMPv6 ND requests
-// }
-// return ret;
- }
- return cMAC_ZERO;
-}
-
-/**
- * \brief Resolves a MAC address from an IPv4 address
- */
-tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
+void ARP_Request4(tInterface *Interface, tIPv4 Address)
{
- int i;
struct sArpRequest4 req;
-
- ENTER("pInterface xAddress", Interface, Address);
-
- // Check for broadcast
- if( Address.L == -1 )
- {
- LOG("Broadcast");
- LEAVE('-');
- return cMAC_BROADCAST;
- }
-
- // Check routing tables if not on this subnet
- if( IPStack_CompareAddress(4, &Address, Interface->Address, Interface->SubnetBits) == 0 )
- {
- tRoute *route = IPStack_FindRoute(4, Interface, &Address);
- // If the next hop is defined, use it
- // - 0.0.0.0 as the next hop means "no next hop / direct"
- if( route && ((tIPv4*)route->NextHop)->L != 0 )
- {
- // Recursion: see /Recursion/
- LOG("Recursing with %s", IPStack_PrintAddress(4, route->NextHop));
- LEAVE('-');
- return ARP_Resolve4(Interface, *(tIPv4*)route->NextHop);
- }
- // No route, fall though
- }
- else
- {
- Uint32 netmask;
- // Check for broadcast
- netmask = IPv4_Netmask(Interface->SubnetBits);
- if( (Address.L & ~netmask) == (0xFFFFFFFF & ~netmask) )
- {
- LOG("Local Broadcast");
- LEAVE('-');
- return cMAC_BROADCAST;
- }
- }
-
- // Check ARP Cache
- Mutex_Acquire( &glARP_Cache4 );
- for( i = 0; i < giARP_Cache4Space; i++ )
- {
- if(gaARP_Cache4[i].IP.L != Address.L) continue;
-
- // Check if the entry needs to be refreshed
- if( now() - gaARP_Cache4[i].LastUpdate > ARP_MAX_AGE ) break;
-
- Mutex_Release( &glARP_Cache4 );
- LOG("Return %x:%x:%x:%x:%x:%x",
- gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1],
- gaARP_Cache4[i].MAC.B[2], gaARP_Cache4[i].MAC.B[3],
- gaARP_Cache4[i].MAC.B[4], gaARP_Cache4[i].MAC.B[5]
- );
- LEAVE('-');
- return gaARP_Cache4[i].MAC;
- }
- giARP_WaitingThreads ++;
- Mutex_Release( &glARP_Cache4 );
-
// Create request
Log_Log("ARP4", "Asking for address %i.%i.%i.%i",
Address.B[0], Address.B[1], Address.B[2], Address.B[3]
// Send Request
Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, buffer);
-
- // Wait for a reply
- Time_ScheduleTimer(NULL, Interface->TimeoutDelay);
- for(;;)
- {
- if( Semaphore_Wait(&gARP_Cache4Semaphore, 1) != 1 )
- {
- giARP_WaitingThreads --;
- Log_Log("ARP4", "Timeout");
- break;
- }
- Log_Debug("ARP4", "Cache change");
-
- Mutex_Acquire( &glARP_Cache4 );
- for( i = 0; i < giARP_Cache4Space; i++ )
- {
- if(gaARP_Cache4[i].IP.L != Address.L) continue;
-
- giARP_WaitingThreads --;
- Mutex_Release( &glARP_Cache4 );
- Log_Debug("ARP4", "Return %02x:%02x:%02x:%02x:%02x:%02x",
- gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1],
- gaARP_Cache4[i].MAC.B[2], gaARP_Cache4[i].MAC.B[3],
- gaARP_Cache4[i].MAC.B[4], gaARP_Cache4[i].MAC.B[5]);
- return gaARP_Cache4[i].MAC;
- }
- Mutex_Release( &glARP_Cache4 );
- }
- {
- tMacAddr ret = {{0,0,0,0,0,0}};
- return ret;
- }
}
-/**
- * \brief Updates the ARP Cache entry for an IPv4 Address
- */
-void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr)
-{
- int i;
- int free = -1;
- int oldest = 0;
-
- // Find an entry for the IP address in the cache
- Mutex_Acquire(&glARP_Cache4);
- for( i = giARP_Cache4Space; i--; )
- {
- if(gaARP_Cache4[oldest].LastUpdate > gaARP_Cache4[i].LastUpdate) {
- oldest = i;
- }
- if( gaARP_Cache4[i].IP.L == SWAddr.L ) break;
- if( gaARP_Cache4[i].LastUpdate == 0 && free == -1 ) free = i;
- }
- // If there was no match, we need to make one
- if(i == -1) {
- if(free != -1)
- i = free;
- else
- i = oldest;
- }
-
- if( memcmp(&gaARP_Cache4[i].MAC, &HWAddr, sizeof(HWAddr)) != 0 )
- {
- Log_Log("ARP4", "Caching %i.%i.%i.%i (%02x:%02x:%02x:%02x:%02x:%02x) in %i",
- SWAddr.B[0], SWAddr.B[1], SWAddr.B[2], SWAddr.B[3],
- HWAddr.B[0], HWAddr.B[1], HWAddr.B[2], HWAddr.B[3], HWAddr.B[4], HWAddr.B[5],
- i
- );
-
- gaARP_Cache4[i].IP = SWAddr;
- gaARP_Cache4[i].MAC = HWAddr;
- gaARP_Cache4[i].LastUpdate = now();
- Semaphore_Signal(&gARP_Cache4Semaphore, giARP_WaitingThreads);
- }
- Mutex_Release(&glARP_Cache4);
-}
-
-#if ARPv6
-/**
- * \brief Updates the ARP Cache entry for an IPv6 Address
- */
-void ARP_UpdateCache6(tIPv6 SWAddr, tMacAddr HWAddr)
-{
- int i;
- int free = -1;
- int oldest = 0;
-
- // Find an entry for the MAC address in the cache
- Mutex_Acquire(&glARP_Cache6);
- for( i = giARP_Cache6Space; i--; )
- {
- if(gaARP_Cache6[oldest].LastUpdate > gaARP_Cache6[i].LastUpdate) {
- oldest = i;
- }
- if( MAC_EQU(gaARP_Cache6[i].MAC, HWAddr) ) break;
- if( gaARP_Cache6[i].LastUpdate == 0 && free == -1 ) free = i;
- }
- // If there was no match, we need to make one
- if(i == -1) {
- if(free != -1)
- i = free;
- else
- i = oldest;
- gaARP_Cache6[i].MAC = HWAddr;
- }
-
- gaARP_Cache6[i].IP = SWAddr;
- gaARP_Cache6[i].LastUpdate = now();
- giARP_LastUpdateID ++;
- Mutex_Release(&glARP_Cache6);
-}
-#endif
-
/**
* \fn void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
* \brief Called when an ARP packet is recieved
req4->SourceMac.B[0], req4->SourceMac.B[1],
req4->SourceMac.B[2], req4->SourceMac.B[3],
req4->SourceMac.B[4], req4->SourceMac.B[5]);
- ARP_UpdateCache4(req4->SourceIP, req4->SourceMac);
+ // Someone has ARPed us, let's cache them
+ HWCache_Set(Adapter, 4, &req4->SourceIP, &req4->SourceMac);
req4->DestIP = req4->SourceIP;
req4->DestMac = req4->SourceMac;
switch( req4->SWSize )
{
case 4:
- ARP_UpdateCache4( req4->SourceIP, From );
+ HWCache_Set(Adapter, 4, &req4->SourceIP, &From);
break;
#if ARPv6
case 6:
Log_Debug("ARP", "Recieved undersized packet (IPv6)");
return ;
}
- ARP_UpdateCache6( req6->SourceIP, From );
+ HWCache_Set(Adapter, 6, &req6->SourceIP, &From );
break;
#endif
default:
--- /dev/null
+/*
+ * Acess2 IP Stack
+ *
+ * hwaddr_resolution.c
+ * - Resolution/caching of hardware addresses
+ */
+#define DEBUG 1
+#include "ipstack.h"
+#include "icmp.h"
+#include "include/adapters_int.h"
+#include "hwaddr_cache.h"
+#include <timers.h>
+#include <semaphore.h>
+#include <limits.h> // *INT_MAX
+
+typedef struct sHWAdddrCache tHWAddrCache;
+typedef struct sHWAdddrCachedAddr tHWAddrCachedAddr;
+
+struct sHWAdddrCache {
+ const tInterface *Interface;
+ tMutex Lock;
+ const int MaxSize;
+ int nAddrs;
+ tHWAddrCachedAddr *First;
+};
+
+struct sHWAdddrCachedAddr {
+ tHWAddrCachedAddr *Next;
+ unsigned int WaitingCount; // While >0, cache will not be reused
+ tSemaphore WaitingSem;
+ void *L3Addr;
+ tMacAddr *HWAddr;
+};
+
+#define PRImacaddr "%02x:%02x:%02x:%02x:%02x:%02x"
+#define FMTmacaddr(a) (a).B[0],(a).B[1],(a).B[2],(a).B[3],(a).B[4],(a).B[5]
+
+// Cache is sorted by usage (most recently used at top)
+
+// === CODE ===
+tHWAddrCache *HWCache_int_GetCache(tAdapter *Adapter, int AddrType)
+{
+ static tHWAddrCache cache_v6 = {.MaxSize=64};
+ static tHWAddrCache cache_v4 = {.MaxSize=64};
+ switch(AddrType)
+ {
+ case 4: return &cache_v4;
+ case 6: return &cache_v6;
+ default:
+ return NULL;
+ }
+}
+
+bool memiszero(const void *mem, size_t length)
+{
+ const Uint8 *mem8 = mem;
+ while( length -- )
+ {
+ if(*mem8 != 0) return false;
+ mem8 ++;
+ }
+ return true;
+}
+
+tMacAddr HWCache_Resolve(tInterface *Interface, const void *DestAddr)
+{
+ const size_t addrsize = IPStack_GetAddressSize(Interface->Type);
+ tHWAddrCache *cache = HWCache_int_GetCache(Interface->Adapter, Interface->Type);
+
+ LOG("DestAddr=%s", IPStack_PrintAddress(Interface->Type, DestAddr));
+
+ // Detect sending packets outside of the local network
+ if( IPStack_CompareAddress(Interface->Type, DestAddr, Interface->Address, Interface->SubnetBits) == 0 )
+ {
+ // Off-net, use a route
+ tRoute *route = IPStack_FindRoute(Interface->Type, Interface, DestAddr);
+ // If a route exists and the gateway isn't empty, use the gateway
+ if( route )
+ {
+ if( !memiszero(route->NextHop, addrsize) )
+ {
+ // Update DestAddr to gateway address
+ DestAddr = route->NextHop;
+ LOG("Via gateway");
+ }
+ else
+ {
+ // Zero gateway means force direct
+ LOG("Force direct");
+ }
+ }
+ else
+ {
+ // No route to host
+ LOG("No route to host");
+ return cMAC_ZERO;
+ }
+ }
+ // Local broadcast
+ else if( IPStack_AddressIsBroadcast(Interface->Type, DestAddr, Interface->SubnetBits) )
+ {
+ // Broadcast, send to bcast mac
+ LOG("Broadcast");
+ return cMAC_BROADCAST;
+ }
+ else
+ {
+ // Fall through
+ }
+ LOG("DestAddr(2)=%s", IPStack_PrintAddress(Interface->Type, DestAddr));
+
+ Mutex_Acquire(&cache->Lock);
+ // 1. Search cache for this address
+ tHWAddrCachedAddr **pnp = &cache->First, *ca;
+ tHWAddrCachedAddr *last = NULL;
+ for( ca = cache->First; ca; ca = ca->Next )
+ {
+ LOG("ca = %p (%s => "PRImacaddr")",
+ ca, IPStack_PrintAddress(Interface->Type, ca->L3Addr),
+ FMTmacaddr(*ca->HWAddr)
+ );
+ if( memcmp(ca->L3Addr, DestAddr, addrsize) == 0 )
+ break;
+ last = ca;
+ pnp = &ca->Next;
+ }
+ if( ca )
+ {
+ // Move to front, return
+ if( cache->First != ca )
+ {
+ ASSERT(pnp != &cache->First);
+ *pnp = ca->Next;
+
+ ca->Next = cache->First;
+ cache->First = ca;
+ LOG("%p(%s) bumped", ca, IPStack_PrintAddress(Interface->Type, ca->L3Addr));
+ }
+
+ // If there's something waiting on this, odds are it's not populated
+ if( ca->WaitingCount > 0 )
+ {
+ ASSERT(ca->WaitingCount != UINT_MAX);
+ ca->WaitingCount ++;
+ Mutex_Release(&cache->Lock);
+
+ // Wait until populated
+ LOG("Waiting on %p", ca);
+ Semaphore_Wait(&ca->WaitingSem, 1);
+
+ Mutex_Acquire(&cache->Lock);
+ ASSERT(ca->WaitingCount > 0);
+ ca->WaitingCount --;
+ }
+ tMacAddr ret = *(tMacAddr*)ca->HWAddr;
+ Mutex_Release(&cache->Lock);
+
+ LOG("Cached "PRImacaddr, FMTmacaddr(ret));
+ return ret;
+ }
+ // 3. If not found:
+ if( cache->nAddrs >= cache->MaxSize )
+ {
+ ASSERTC(cache->nAddrs, ==, cache->MaxSize);
+ ASSERT(last);
+ // TODO: Need to pick the oldest entry with WaitingThreads==0
+ ASSERT(ca->WaitingCount == 0);
+ // Reuse the oldest item
+ ca = last;
+ LOG("Reuse entry for %p(%s)", ca, IPStack_PrintAddress(Interface->Type, ca->L3Addr));
+ }
+ else
+ {
+ cache->nAddrs ++;
+ ca = calloc( 1, sizeof(*ca) + addrsize + sizeof(tMacAddr) );
+ ca->L3Addr = ca+1;
+ ca->HWAddr = (void*)( (char*)ca->L3Addr + addrsize );
+ LOG("New entry %p", ca);
+ }
+ memcpy(ca->L3Addr, DestAddr, addrsize);
+ memset(ca->HWAddr, 0, sizeof(tMacAddr));
+
+ // Shift to front of list
+ if( cache->First != ca )
+ {
+ *pnp = ca->Next;
+ ca->Next = cache->First;
+ cache->First = ca;
+ }
+
+ // Mark cache entry as being waited upon
+ ASSERT(ca->WaitingCount == 0);
+ ca->WaitingCount = 1;
+ // Then release cache lock (so inbound packets can manipulate it)
+ Mutex_Release(&cache->Lock);
+
+ // Send a request for the address
+ switch(Interface->Type)
+ {
+ case 4: ARP_Request4(Interface, *(tIPv4*)DestAddr); break;
+ //case 6: ICMPv6_RequestND(Interface, DestAddr); break;
+ default:
+ ASSERTC(Interface->Type, ==, 4);
+ ASSERTC(Interface->Type, ==, 6);
+ break;
+ }
+
+ // Wait for up to 3000ms for the entry to populate
+ LOG("Waiting on new entry");
+ Time_ScheduleEvent(3000);
+ int rv = Semaphore_Wait(&ca->WaitingSem, 1);
+
+ // Lock, reduce waiting count, grab return, and release
+ Mutex_Acquire(&cache->Lock);
+ ASSERT(ca->WaitingCount > 0);
+ ca->WaitingCount --;
+ tMacAddr ret = *(tMacAddr*)ca->HWAddr;
+ Mutex_Release(&cache->Lock);
+
+ // NOTE: If entry wasn't populated, we'd return 0 anyway, this is
+ // just for logging purposes
+ if( rv != 1 )
+ {
+ // Interrupted, return zero MAC
+ LOG("Timeout/interrupt, return zero");
+ return cMAC_ZERO;
+ }
+
+ // Release `ca` (on error, HWAddr will be nul)
+ LOG("Requested "PRImacaddr, FMTmacaddr(ret));
+ return ret;
+}
+
+void HWCache_Set(tAdapter *Adapter, int AddrType, const void *L3Addr, const tMacAddr *HWAddr)
+{
+ const size_t addrsize = IPStack_GetAddressSize(AddrType);
+ tHWAddrCache *cache = HWCache_int_GetCache(Adapter, AddrType);
+ LOG("Set %s = "PRImacaddr,
+ IPStack_PrintAddress(AddrType, L3Addr),
+ FMTmacaddr(*HWAddr)
+ );
+ // 1. Locate an existing entry
+ Mutex_Acquire(&cache->Lock);
+ tHWAddrCachedAddr *last_unused = NULL;
+ tHWAddrCachedAddr **pnp = &cache->First;
+ for( tHWAddrCachedAddr *ca = cache->First; ca; ca = ca->Next )
+ {
+ ASSERT(ca->Next != ca);
+ ASSERT(!ca->Next || ca->Next->Next != ca);
+
+ LOG("ca = %p (%s => "PRImacaddr")",
+ ca, IPStack_PrintAddress(AddrType, ca->L3Addr), FMTmacaddr(*ca->HWAddr)
+ );
+ if( ca->WaitingCount == 0 )
+ last_unused = ca;
+ pnp = &ca->Next;
+
+ // 2. If found, set the cache and poke waiting threads
+ if( memcmp(L3Addr, ca->L3Addr, addrsize) == 0 )
+ {
+ if( ca->WaitingCount )
+ {
+ memcpy(ca->HWAddr, HWAddr, sizeof(tMacAddr));
+ Semaphore_Signal(&ca->WaitingSem, INT_MAX);
+ LOG("Found and cached");
+ }
+ else if( memcmp(HWAddr, ca->HWAddr, sizeof(tMacAddr)) )
+ {
+ LOG("Differs to cache");
+ }
+ else
+ {
+ LOG("Already known");
+ }
+ Mutex_Release(&cache->Lock);
+ return ;
+ }
+ }
+ // No existing entry, cache just in case
+ if( cache->nAddrs < cache->MaxSize )
+ {
+ // Create new
+ cache->nAddrs ++;
+ tHWAddrCachedAddr *ca = calloc(1,sizeof(tHWAddrCachedAddr)+addrsize+sizeof(tMacAddr));
+ *pnp = ca;
+ ca->L3Addr = ca+1;
+ ca->HWAddr = (void*)( (char*)ca->L3Addr + addrsize );
+ memcpy(ca->L3Addr, L3Addr, addrsize);
+ memcpy(ca->HWAddr, HWAddr, sizeof(tMacAddr));
+ LOG("Cache in new entry");
+ }
+ else if( last_unused )
+ {
+ tHWAddrCachedAddr *ca = last_unused;
+ memcpy(ca->L3Addr, L3Addr, addrsize);
+ memcpy(ca->HWAddr, HWAddr, sizeof(tMacAddr));
+ // Maintain position
+ LOG("Cache in old entry");
+ }
+ else
+ {
+ // None unused! What is this madness?
+ LOG("Not cached... cache being thrashed?");
+ }
+ Mutex_Release(&cache->Lock);
+}
--- /dev/null
+/*
+ */
+#ifndef _HWADDR_CACHE_H_
+#define _HWADDR_CACHE_H_
+
+extern tMacAddr HWCache_Resolve(tInterface *Interface, const void *L2Addr);
+extern void HWCache_Set(tAdapter *Adapter, int AddrType, const void *L2Addr, const tMacAddr *HWAddr);
+
+
+extern void ARP_Request4(tInterface *Interface, tIPv4 Address);
+extern void ICMPv6_RequestND(tInterface *Interface, const tIPv6 *Address);
+
+#endif
+
extern int IPStack_AddFile(tSocketFile *File);
extern int IPStack_GetAddressSize(int AddressType);
extern int IPStack_CompareAddress(int AddressType, const void *Address1, const void *Address2, int CheckBits);
+extern bool IPStack_AddressIsBroadcast(int AddrType, const void *Addr, int SubnetBits);
extern const char *IPStack_PrintAddress(int AddressType, const void *Address);
-extern tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
+extern tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, const void *Address);
#endif
#include "ipstack.h"
#include "link.h"
#include "ipv4.h"
+#include "hwaddr_cache.h"
#include "firewall.h"
// === CONSTANTS ===
extern tInterface *gIP_Interfaces;
extern void ICMP_Initialise();
extern int ICMP_Ping(tInterface *Interface, tIPv4 Addr);
-extern tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address);
-extern void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr);
// === PROTOTYPES ===
int IPv4_Initialise();
length = IPStack_Buffer_GetLength(Buffer);
// --- Resolve destination MAC address
- to = ARP_Resolve4(Iface, Address);
+ to = HWCache_Resolve(Iface, &Address);
if( MAC_EQU(to, cMAC_ZERO) ) {
// No route to host
Log_Notice("IPv4", "No route to host %i.%i.%i.%i",
// Get Data and Data Length
dataLength = ntohs(hdr->TotalLength) - sizeof(tIPv4Header);
data = &hdr->Options[0];
-
- // Populate ARP cache from sniffing.
- // - Downside: Poisoning, polluting from routed packets
- //ARP_UpdateCache4(hdr->Source, From);
// Get Interface (allowing broadcasts)
iface = IPv4_GetInterface(Adapter, hdr->Destination, 1);
}
else {
// Routed packets
+ // Drop the packet if the TTL is zero
+ if( hdr->TTL == 0 ) {
+ Log_Warning("IPv4", "TODO: Send ICMP-Timeout when TTL exceeded");
+ return ;
+ }
+ hdr->TTL --;
+
ret = IPTables_TestChain("FORWARD",
4, &hdr->Source, &hdr->Destination,
hdr->Protocol, 0,
// Routing
if(!iface)
{
- #if 0
- tMacAddr to;
- tRoute *rt;
-
-
- // TODO: Put this in another thread to avoid delays in the RX thread
- Log_Debug("IPv4", "Route the packet");
- // Drop the packet if the TTL is zero
- if( hdr->TTL == 0 ) {
- Log_Warning("IPv4", "TODO: Send ICMP-Timeout when TTL exceeded");
- return ;
- }
-
- hdr->TTL --;
-
- rt = IPStack_FindRoute(4, NULL, &hdr->Destination); // Get the route (gets the interface)
- if( !rt || !rt->Interface )
- return ;
- to = ARP_Resolve4(rt->Interface, hdr->Destination); // Resolve address
- if( MAC_EQU(to, cMAC_ZERO) )
- return ;
-
- // Send packet
- Log_Log("IPv4", "Forwarding packet to %i.%i.%i.%i (via %i.%i.%i.%i)",
- hdr->Destination.B[0], hdr->Destination.B[1],
- hdr->Destination.B[2], hdr->Destination.B[3],
- ((tIPv4*)rt->NextHop)->B[0], ((tIPv4*)rt->NextHop)->B[1],
- ((tIPv4*)rt->NextHop)->B[2], ((tIPv4*)rt->NextHop)->B[3]);
- Log_Warning("IPv4", "TODO: Implement forwarding with tIPStackBuffer");
-// Link_SendPacket(rt->Interface->Adapter, IPV4_ETHERNET_ID, to, Length, Buffer);
- #endif
-
+ //IPStack_RoutePacket(4, &hdr->Destination, Length, Buffer);
return ;
}
// Populate ARP cache from recieved packets
// - Should be safe
- ARP_UpdateCache4(hdr->Source, From);
+ if( IPStack_CompareAddress(4, &hdr->Source, iface->Address, iface->SubnetBits) )
+ {
+ HWCache_Set(Adapter, 4, &hdr->Source, &From);
+ }
// Send it on
if( !gaIPv4_Callbacks[hdr->Protocol] ) {
#include "link.h"
#include "ipv6.h"
#include "firewall.h"
+#include "hwaddr_cache.h"
// === IMPORTS ===
extern tInterface *gIP_Interfaces;
* \param Data Packet Data
* \return Boolean Success
*/
-int IPv6_SendPacket(tInterface *Iface, tIPv6 Destination, int Protocol, size_t Length, const void *Data)
+int IPv6_SendPacket(tInterface *Iface, tIPv6 Destination, int Protocol, tIPStackBuffer *Buffer)
{
- return 0;
+ size_t length = IPStack_Buffer_GetLength(Buffer);
+
+ // Resolve destination
+ tMacAddr to = HWCache_Resolve(Iface, &Destination);
+ if( MAC_EQU(to, cMAC_ZERO) ) {
+ // No route to host
+ return 0;
+ }
+
+ // Build up header
+ tIPv6Header hdr;
+ hdr.Version = 6;
+ hdr.TrafficClass = 0;
+ hdr.FlowLabel = 0;
+ hdr.Head = htonl(hdr.Head);
+ hdr.PayloadLength = htons(length);
+ hdr.NextHeader = Protocol; // TODO: Routing header?
+ hdr.HopLimit = 64; // TODO: Configurable TTL
+ hdr.Source = *(tIPv6*)Iface->Address;
+ hdr.Destination = Destination;
+
+ IPStack_Buffer_AppendSubBuffer(Buffer, sizeof(hdr), 0, &hdr, NULL, NULL);
+
+ Link_SendPacket(Iface->Adapter, IPV6_ETHERNET_ID, to, Buffer);
+
+ return 1;
}
/**
if(nextHeader == 0)
{
// TODO: Parse the options (actually, RFC2460 doesn't specify any)
+ // Two Defined: Pad1 and PadN
}
// Routing Options
else if(nextHeader == 43)
}
else
{
- break; // Unknown, pass on
+ break; // Unknown, pass to next layer
}
nextHeader = optionHdr->NextHeader;
dataPtr += (optionHdr->Length + 1) * 8; // 8-octet length (0 = 8 bytes long)
}
else {
// Routed packets
+
+ // If routing is disabled globally, or if it's disabled for v6 only, drop
+ if( false || false )
+ {
+ return ;
+ }
+ // TODO: Defer routing of packet
+ LOG("Route the packet");
+ // Drop the packet if the TTL is zero
+ if( hdr->HopLimit == 0 ) {
+ Log_Warning("IPv6", "TODO: Send ICMP-Timeout when TTL exceeded");
+ return ;
+ }
+ hdr->HopLimit --;
+
ret = IPTables_TestChain("FORWARD",
6, &hdr->Source, &hdr->Destination,
hdr->NextHeader, 0,
// Routing
if(!iface)
{
- #if 0
- tMacAddr to;
- tRoute *rt;
-
- Log_Debug("IPv6", "Route the packet");
- // Drop the packet if the TTL is zero
- if( hdr->HopLimit == 0 ) {
- Log_Warning("IPv6", "TODO: Sent ICMP-Timeout when TTL exceeded");
- return ;
- }
-
- hdr->HopLimit --;
-
- rt = IPStack_FindRoute(6, NULL, &hdr->Destination); // Get the route (gets the interface)
- to = ICMP6_ResolveHWAddr(rt->Interface, hdr->Destination); // Resolve address
-
- // Send packet
- Log_Log("IPv6", "Forwarding packet");
- Link_SendPacket(rt->Interface->Adapter, IPV6_ETHERNET_ID, to, Length, Buffer);
- #endif
-
+ // TODO: Use tIPStackBuffer instead, for refcounting
+ //IPStack_RoutePacket(6, &hdr->Destination, Length, Buffer);
return ;
}
+ // Populate cache
+ // - TODO: Populate when routing using source address match for iface
+ if( IPStack_CompareAddress(6, &hdr->Source, iface->Address, iface->SubnetBits) )
+ {
+ HWCache_Set(Adapter, 6, &hdr->Source, &From);
+ }
+
// Send it on
if( !gaIPv6_Callbacks[hdr->NextHeader] ) {
Log_Log("IPv6", "Unknown Protocol %i", hdr->NextHeader);
#define IPV6_ETHERNET_ID 0x86DD
extern int IPv6_RegisterCallback(int ID, tIPCallback Callback);
-extern int IPv6_SendPacket(tInterface *Iface, tIPv6 Destination, int Protocol, size_t Length, const void *Data);
+extern int IPv6_SendPacket(tInterface *Iface, tIPv6 Destination, int Protocol, tIPStackBuffer *Buffer);
#endif
return 0;
}
+bool IPStack_AddressIsBroadcast(int AddrType, const void *Addr, int SubnetBits)
+{
+ const size_t addrsize = IPStack_GetAddressSize(AddrType);
+ const Uint8 *addr = Addr;
+
+ ASSERTC( SubnetBits, >=, 0 );
+ ASSERTC( SubnetBits, <=, addrsize * 8 );
+ const size_t host_bits = addrsize*8 - SubnetBits;
+
+ for( int i = 0; i < host_bits/8; i ++ )
+ {
+ if( addr[addrsize-i-1] != 0xFF )
+ return false;
+ }
+ Uint8 mask = 0xFF >> (8-(host_bits%8));
+ if( (addr[addrsize-host_bits/8-1] & mask) != mask )
+ return false;
+ return true;
+}
+
const char *IPStack_PrintAddress(int AddressType, const void *Address)
{
switch( AddressType )
// - Route Management
tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric);
tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric);
-tRoute *_Route_FindInterfaceRoute(int AddressType, void *Address);
-tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
+tRoute *_Route_FindInterfaceRoute(int AddressType, const void *Address);
+tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, const void *Address);
// - Individual Routes
int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data);
/**
* \brief Locates what interface should be used to get directly to an address
*/
-tRoute *_Route_FindInterfaceRoute(int AddressType, void *Address)
+tRoute *_Route_FindInterfaceRoute(int AddressType, const void *Address)
{
tRoute *best = NULL, *rt;
int addrSize = IPStack_GetAddressSize(AddressType);
/**
*/
-tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
+tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, const void *Address)
{
tRoute *rt;
tRoute *best = NULL;
checksum[0] = htons( ~IPv4_Checksum(buf, sizeof(buf)) ); // Partial checksum
}
Header->Checksum = htons( IPv4_Checksum(checksum, sizeof(checksum)) ); // Combine the two
- IPv6_SendPacket(Conn->Interface, Conn->RemoteIP.v6, IP4PROT_TCP, Length, Data);
+ IPv6_SendPacket(Conn->Interface, Conn->RemoteIP.v6, IP4PROT_TCP, buffer);
break;
}
}
#define USE_KERNEL_MAGIC 1
+extern void Validate_VirtualMemoryUsage(void);
+
// === PROTOTYPES ===
int Keyboard_Install(char **Arguments);
int Keyboard_Cleanup(void);
{ .Type = &gKB_NodeType }
};
#if USE_KERNEL_MAGIC
- int giKB_MagicAddress = 0;
- int giKB_MagicAddressPos = 0;
+tDebugHook gKB_DebugHookInfo;
#endif
// === CODE ===
Log_Error("Keyboard", "TODO: Implement Keyboard_RemoveInstance");
}
+inline bool IsPressed(tKeyboard *Kb, Uint8 KeySym)
+{
+ return !!(Kb->KeyStates[KeySym/8] & (1 << (KeySym&7)));
+}
+
/*
* Handle a key press/release event
* - See Input/Keyboard/include/keyboard.h
break;
}
- // --- Check for Kernel Magic Combos
+ // Magic debug hooks
#if USE_KERNEL_MAGIC
- if(bPressed
- && Source->KeyStates[KEYSYM_LEFTCTRL/8] & (1 << (KEYSYM_LEFTCTRL&7))
- && Source->KeyStates[KEYSYM_LEFTALT/8] & (1 << (KEYSYM_LEFTALT &7)) )
+ if(bPressed && IsPressed(Source, KEYSYM_LEFTCTRL) && IsPressed(Source, KEYSYM_LEFTALT))
{
- int val;
- switch(trans)
- {
- case '0': val = 0; goto _av; case '1': val = 1; goto _av;
- case '2': val = 2; goto _av; case '3': val = 3; goto _av;
- case '4': val = 4; goto _av; case '5': val = 5; goto _av;
- case '6': val = 6; goto _av; case '7': val = 7; goto _av;
- case '8': val = 8; goto _av; case '9': val = 9; goto _av;
- case 'a': val = 10; goto _av; case 'b': val = 11; goto _av;
- case 'c': val = 12; goto _av; case 'd': val = 13; goto _av;
- case 'e': val = 14; goto _av; case 'f': val = 15; goto _av;
- _av:
- if(giKB_MagicAddressPos == BITS/4) break;
- giKB_MagicAddress |= (Uint)val << giKB_MagicAddressPos;
- giKB_MagicAddressPos ++;
- break;
-
- // Instruction Tracing
- case 't':
- Log("Toggle instruction tracing on %i\n", giKB_MagicAddress);
- Threads_ToggleTrace( giKB_MagicAddress );
- giKB_MagicAddress = 0; giKB_MagicAddressPos = 0;
- return;
-
- // Thread List Dump
- case 'p': Threads_Dump(); return;
- // Heap Statistics
- case 'h': Heap_Stats(); return;
- // PMem Statistics
- case 'm': MM_DumpStatistics(); return;
- // Dump Structure
- case 's': return;
+ if( trans == '~' ) {
+ // TODO: Latch mode
}
+ else {
+ char str[5]; // utf8 only supports 8 bytes
+ size_t len = WriteUTF8((Uint8*)str, trans);
+ str[len] = '\0';
+ DebugHook_HandleInput(&gKB_DebugHookInfo, len, str);
+ }
+ return ;
}
#endif
+ // Ctrl-Alt-Del == Reboot
#if defined(ARCHDIR_is_x86) || defined(ARCHDIR_is_x86_64)
if(bPressed
- && Source->KeyStates[KEYSYM_LEFTCTRL/8] & (1 << (KEYSYM_LEFTCTRL&7))
- && Source->KeyStates[KEYSYM_LEFTALT/8] & (1 << (KEYSYM_LEFTALT &7)) )
+ && (IsPressed(Source, KEYSYM_LEFTCTRL) || IsPressed(Source, KEYSYM_RIGHTCTRL))
+ && (IsPressed(Source, KEYSYM_LEFTALT) || IsPressed(Source, KEYSYM_LEFTALT))
+ )
{
if( HIDKeySym == KEYSYM_DELETE )
{
UNIMPLEMENTED();
}
-void udi_assert(udi_boolean_t bool)
+void udi_assert(udi_boolean_t bool_value)
{
UNIMPLEMENTED();
}
$V$(LD) -g $(LDFLAGS) -o $@ $(CRTBEGIN) $(OBJ) $(LIBGCC_PATH) $(CRTEND)
$V$(DISASM) $(_BIN) > $(_OBJPREFIX)$(BIN).dsm
-$(OBJ): $(_OBJPREFIX)%.o: %.c
+$(_OBJPREFIX)%.o: %.c
@echo [CC] -o $@
ifneq ($(_OBJPREFIX),)
@mkdir -p $(dir $@)
$V$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
$V$(CC) -M -MP -MT $@ $(CPPFLAGS) $< -o $(_OBJPREFIX)$*.dep
+$(_OBJPREFIX)%.o: %.cpp
+ @echo [CXX] -o $@
+ifneq ($(_OBJPREFIX),)
+ @mkdir -p $(dir $@)
+endif
+ $V$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@ -MQ $@ -MP -MD -MF $(_OBJPREFIX)$*.dep
+
$(OUTPUTDIR)Libs/libld-acess.so:
@make -C $(ACESSDIR)/Usermode/Libraries/ld-acess.so_src/
$(OUTPUTDIR)Libs/%:
t_sysFInfo info;
int rv = _SysFInfo(fd, &info, 0);
- if( !rv ) {
+ if( rv == -1 ) {
return -1;
}
+ _SysDebug("fstat(fd=%i,buf=%p)", fd, buf);
+
// TODO: Populate buf
- buf->st_mode = 0;
-// memset(buf, 0, sizeof(*buf));
+ buf->st_dev = info.mount;
+ buf->st_ino = info.inode;
+ if( info.flags & FILEFLAG_SYMLINK )
+ buf->st_mode = S_IFLNK;
+ else if( info.flags & FILEFLAG_DIRECTORY )
+ buf->st_mode = S_IFDIR;
+ else
+ buf->st_mode = S_IFREG;
+ // TODO: User modes (assume 660)
+ buf->st_mode |= 0660;
+ buf->st_nlink = 1;
+ buf->st_uid = info.uid;
+ buf->st_gid = info.gid;
+ buf->st_rdev = NULL;
+ buf->st_size = info.size;
+ buf->st_blksize = 512;
+ buf->st_blocks = (info.size+511)/512;
+ buf->st_atime = info.atime;
+ buf->st_mtime = info.mtime;
+ buf->st_ctime = info.ctime;
return 0;
}
// TODO: DNS Lookups
// ? /Acess/Conf/Nameservers
// ? /Acess/Conf/Hosts
+ //count = Net_LookupDNS(node, service, NULL);
+ //
}
// 3. No Match, chuck sad
}
}
- struct addrinfo *ai;
- for( ai = ret; ai; ai = ai->ai_next)
+ for( struct addrinfo *ai = ret; ai; ai = ai->ai_next)
{
struct sockaddr_in *in = (void*)ai->ai_addr;
struct sockaddr_in6 *in6 = (void*)ai->ai_addr;