extern void Threads_Dump(void);
extern void KernelPanic_SetMode(void);
extern void KernelPanic_PutChar(char Ch);
+extern void IPStack_SendDebugText(const char *Text);
// === PROTOTYPES ===
static void Debug_Putchar(char ch);
#if LOCK_DEBUG_OUTPUT
tShortSpinlock glDebug_Lock;
#endif
+// - Disabled because it breaks shit
+ int gbSendNetworkDebug = 0;
// === CODE ===
static void Debug_Putchar(char ch)
{
Debug_PutCharDebug(ch);
+
if( !gbDebug_IsKPanic )
{
if(gbInPutChar) return ;
}
else
KernelPanic_PutChar(ch);
+
+ if( gbSendNetworkDebug )
+ {
+ char str[2] = {ch, 0};
+ IPStack_SendDebugText(str);
+ }
}
static void Debug_Puts(int UseKTerm, const char *Str)
}
else
for( len = 0; Str[len]; len ++ );
-
+
+ if( gbSendNetworkDebug )
+ IPStack_SendDebugText(Str);
+
// Output to the kernel terminal
if( UseKTerm && !gbDebug_IsKPanic && giDebug_KTerm != -1)
{
void Debug_Fmt(int bUseKTerm, const char *format, va_list args)
{
char buf[DEBUG_MAX_LINE_LEN];
- int len;
+// int len;
buf[DEBUG_MAX_LINE_LEN-1] = 0;
- len = vsnprintf(buf, DEBUG_MAX_LINE_LEN-1, format, args);
+ /*len = */vsnprintf(buf, DEBUG_MAX_LINE_LEN-1, format, args);
//if( len < DEBUG_MAX_LINE )
// do something
Debug_Puts(bUseKTerm, buf);
ret->Node.Type = &gIP_AdapterType;
ret->Node.ImplPtr = ret;
- // TODO: Locking
+ Mutex_Acquire( &glIP_Adapters );
gpIP_AdapterList_Last->Next = ret;
gpIP_AdapterList_Last = ret;
+ Mutex_Release( &glIP_Adapters );
// Watch the adapter for incoming packets
tTID tid = Proc_SpawnWorker(Adapter_int_WatchThread, ret);
return 0;
}
+// --- Broadcast Debugging ---
+extern Uint16 IPv4_Checksum(const void *Buf, size_t Length);
+void IPStack_SendDebugText(const char *Text)
+{
+ const Uint8 pkt_hdr[] = {
+ 0xFF,0xFF, 0xFF,0xFF, 0xFF,0xFF,
+ 0x00,0x00, 0x00,0x00, 0x00,0x00,
+ 0x08,0x00,
+
+ 0x45,0x00, // Version/Length, DiffServices
+ 0xFF,0xFF, // Total Length
+ 0x00,0x00, // Identifcation
+ 0x00,0x00, 0xFF,0x11, // Flags,Fragment, TTL=255,proto=UDP
+ 0x00,0x00, // Header checksum
+ 0x00,0x00,0x00,0x00, // Source
+ 0xFF,0xFF,0xFF,0xFF, // Destination
+
+ 0x80,0x00, 0x80,0x00,
+ 0xFF,0xFF, 0xFF,0xFF,
+ };
+ static tShortSpinlock lLock;
+
+ // Fast return if there's no avaliable adapters
+ if( !gpIP_AdapterList )
+ return ;
+
+ if( CPU_HAS_LOCK(&lLock) )
+ return ; // Nested!
+ SHORTLOCK(&lLock);
+ __asm__ __volatile__ ("sti"); // Start interrupts (x86 specific)
+
+ // Cache packets until a newline
+ static char cache[1500 - (sizeof(pkt_hdr) + 4)];
+ static int cache_len;
+
+ int len = strlen(Text);
+
+ // Append to cache
+ strncpy(cache + cache_len, Text, sizeof(cache) - cache_len);
+ cache_len += len;
+ // TODO: Detect overflows.
+
+ // If there's no newline, only buffer
+ if( strpos(Text, '\n') == -1 ) {
+ SHORTREL(&lLock);
+ return ;
+ }
+
+ // Build packet
+ int link_checksum_ofs = sizeof(pkt_hdr) + cache_len;
+ char buffer[sizeof(pkt_hdr) + cache_len + 4];
+
+ memcpy(buffer, pkt_hdr, sizeof(pkt_hdr));
+ memcpy(buffer + sizeof(pkt_hdr), cache, cache_len);
+
+ *(Uint16*)&buffer[14+2] = BigEndian16( sizeof(pkt_hdr)-14 + cache_len ); // IP Size
+ *(Uint16*)&buffer[14+10] = BigEndian16( 0 ); // IP Header
+ *(Uint16*)&buffer[14+20+4] = BigEndian16( 8+cache_len ); // UDP Size
+ *(Uint16*)&buffer[14+20+6] = BigEndian16( 0 ); // UDP Checksum
+ *(Uint32*)&buffer[link_checksum_ofs] = BigEndian32( 0 ); // 802.3 checksum?
+ // TODO: Calculate checksums
+ *(Uint16*)&buffer[14+10] = BigEndian16( IPv4_Checksum(buffer+14,20) ); // IP Header
+
+ // Create buffer
+ tIPStackBuffer *buf = IPStack_Buffer_CreateBuffer(1);
+ IPStack_Buffer_AppendSubBuffer(buf, link_checksum_ofs+4, 0, buffer, NULL, NULL);
+
+ // Send 'er off
+ for( tAdapter *a = gpIP_AdapterList; a; a = a->Next )
+ {
+ a->Type->SendPacket( a->CardHandle, buf );
+ }
+
+ IPStack_Buffer_DestroyBuffer(buf);
+
+ cache_len = 0;
+
+ SHORTREL(&lLock);
+}
+