Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 914 → Rev 913

/kernel/branches/kolibri_pe/core/dll.c
277,13 → 277,12
( raw[1] == 0x30305445) ) )
 
{
DBG("leagacy Kolibri application");
DBG("leagacy Kolibri application\n");
int tmp = mnt_exec(raw, raw_size, path, cmdline, flags);
DBG(" pid %x\n",tmp);
return tmp;
}
 
if( ! validate_pe(raw, raw_size, true) )
if( ! validate_pe(raw, raw_size) )
{
DBG("invalid executable file %s\n", path);
mem_free(raw);
290,9 → 289,6
return -31;
}
 
dos = (PIMAGE_DOS_HEADER)raw;
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew);
 
pathsize = strlen(path)+1;
 
if( cmdline )
363,7 → 359,8
DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n",
ex_stack, ex_stack->path, ex_stack->cmdline);
 
return pe_app_param(path, raw, ex_pg_dir, ex_stack);
pe_app_param(path, raw, ex_pg_dir, ex_stack);
return 0;
};
 
#define master_tab (page_tabs+ (page_tabs>>10))
397,10 → 394,6
 
size_t img_size;
count_t img_pages;
size_t stack_size;
addr_t img_stack;
addr_t *pte;
 
count_t i;
u32_t tmp;
 
415,27 → 408,19
 
list_initialize(&current_slot->dll_list);
 
pte = (addr_t*)page_tabs;
img_pages = img_size >> 12;
 
stack_size = (nt->OptionalHeader.SizeOfStackReserve + 4095) & ~4095;
img_stack = 0x7FFFF000 - stack_size;
stack_size>>= 12;
for(i = 0; i < img_pages; i++)
{
addr_t page = core_alloc(0);
((u32_t*)page_tabs)[i] = page | 7; /* FIXME */
}
 
while (img_pages--)
*pte++ = 2;
 
pte = &((addr_t*)page_tabs)[img_stack>>12];
 
while(stack_size--)
*pte++ = 0x02;
 
addr_t stack_page = ((addr_t)ex_stack-OS_BASE) & ~4095;
((u32_t*)page_tabs)[0x7FFFF000>>12] = stack_page | 7;
 
*pte = stack_page | 7;
create_image(0, raw);
 
create_image(0, raw, false);
 
init_user_heap();
 
if (! link_pe(0))
445,7 → 430,6
"int $0x40"::"a"(-1));
};
 
 
// __asm__ __volatile__ (
// "xchgw %bx, %bx");
 
497,7 → 481,7
return NULL;
};
 
if( ! validate_pe(raw, raw_size, false) )
if( ! validate_pe(raw, raw_size) )
{
DBG("invalid pe file %s\n", path);
mem_free(raw);
524,7 → 508,7
return NULL;
};
 
create_image(img_base, (addr_t)raw, false);
create_image(img_base, (addr_t)raw);
 
mem_free(raw);
 
625,7 → 609,6
{
PIMAGE_IMPORT_BY_NAME ord;
addr_t addr;
*iat=0;
 
if ( thunk->u1.AddressOfData == 0 )
break;
632,9 → 615,7
 
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
{
u16_t ordinal;
ordinal = thunk->u1.Ordinal & 0xFFFF;
*iat = functions[ordinal-exp->Base] + exp_dll->img_base;
// printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF);
break;
}
else
641,6 → 622,7
{
ord = MakePtr(PIMAGE_IMPORT_BY_NAME,
thunk->u1.AddressOfData, img_base);
*iat=0;
 
DBG("import %s ", ord->Name);
 
657,7 → 639,7
{
u16_t ordinal;
ordinal = ordinals[ind];
DBG("ordinal %d\t\tat %x\n", ordinal, functions[ordinal] + exp_dll->img_base);
DBG(" \t\tat %x\n", functions[ordinal] + exp_dll->img_base);
*iat = functions[ordinal] + exp_dll->img_base;
break;
};
/kernel/branches/kolibri_pe/core/heap.inc
32,20 → 32,20
sub eax, 4096
ret
@@:
mov edx, [ebx+APPDATA.mem_size]
add edx, 4095
and edx, not 4095
mov [ebx+APPDATA.mem_size], edx
mov esi, [ebx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov [ebx+APPDATA.mem_size], esi
mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], edx
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
 
sub eax, edx
shr edx, 10
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+edx], ecx
mov [page_tabs+esi], ecx
ret
 
align 4
/kernel/branches/kolibri_pe/core/pe.c
40,6 → 40,7
 
int __stdcall strncmp(const char *s1, const char *s2, size_t n);
 
void __export create_image(addr_t img_base, addr_t raw) asm ("CreateImage");
bool link_image(addr_t img_base);
 
md_t* __fastcall load_image(const char *path);
58,7 → 59,7
};
*/
 
bool validate_pe(void *raw, size_t raw_size, bool is_exec)
bool validate_pe(void *raw, size_t raw_size)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
79,18 → 80,9
if(nt->Signature != IMAGE_NT_SIGNATURE)
return false;
 
if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
return false;
 
if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
return false;
 
if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return false;
 
if( is_exec && nt->OptionalHeader.ImageBase != 0)
return false;
 
if(nt->OptionalHeader.SectionAlignment < PAGE_SIZE)
{
if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment)
135,7 → 127,7
return NULL;
};
 
if( ! validate_pe(raw, raw_size, false) )
if( ! validate_pe(raw, raw_size) )
{
DBG("invalid pe file %s\n", path);
mem_free(raw);
158,7 → 150,7
 
img_base = img_md->base;
 
create_image(img_base, (addr_t)raw, true);
create_image(img_base, (addr_t)raw);
 
mem_free(raw);
 
198,7 → 190,7
*/
 
 
void create_image(addr_t img_base, addr_t raw, bool force_clear)
void create_image(addr_t img_base, addr_t raw)
{
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt;
231,16 → 223,13
if(img_sec->SizeOfRawData)
sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData);
 
if(force_clear)
{
sec_size = (img_sec->Misc.VirtualSize + sec_align -1) & -sec_align;
 
if(sec_size > img_sec->SizeOfRawData)
sec_clear(dest_ptr + img_sec->SizeOfRawData,
sec_size - img_sec->SizeOfRawData);
};
img_sec++;
};
}
 
if(nt->OptionalHeader.DataDirectory[5].Size)
{
/kernel/branches/kolibri_pe/core/taskman.inc
146,12 → 146,11
test al, al
jnz @b
 
lea edi, [cmdline]
mov dword [edi],0
mov esi, [cmd_line]
test esi, esi
jz .no_cmdline
 
lea edi, [cmdline]
lea ecx, [edi+255]
mov [edi+252], dword 0
@@:
227,8 → 226,8
 
mov ecx, [hdr_mem]
mov edi, [file_size]
; add edi, 4095
; and edi, not 4095
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
 
247,8 → 246,8
mov eax, [save_cr3]
call set_cr3
 
mov [application_table_status], 0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
mov [application_table_status], 0 ;unlock application_table_status mutex
 
pop edi
pop esi
434,8 → 433,8
 
DEBUGF 1,"%s",new_process_running
.err:
mov [application_table_status], 0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
mov [application_table_status], 0 ;unlock application_table_status mutex
 
pop edi
pop esi
/kernel/branches/kolibri_pe/core/export.asm
3,7 → 3,7
 
 
.section .drectve
# .ascii " -export:CreateImage" # cdecl
.ascii " -export:CreateImage" # cdecl
.ascii " -export:LoadFile" # stdcall
 
.ascii " -export:Kmalloc" # eax FIXME
/kernel/branches/kolibri_pe/drivers/ati2d.asm
1195,186 → 1195,62
dd (0x5D4D shl 16)+VID_ATI, init_r200 ;R480 X850
dd (0x5D52 shl 16)+VID_ATI, init_r200 ;R480 X850
 
dd (0x7100 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x7101 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1800 XT
dd (0x7102 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1800
dd (0x7103 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V7200
dd (0x7104 shl 16)+VID_ATI, init_r500 ;FireGL V7200
dd (0x7105 shl 16)+VID_ATI, init_r500 ;FireGL V5300
dd (0x7106 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V7100
dd (0x7108 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x7109 shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710A shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710B shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710C shl 16)+VID_ATI, init_r500 ;Radeon X1800
dd (0x710E shl 16)+VID_ATI, init_r500 ;FireGL V7300
dd (0x710F shl 16)+VID_ATI, init_r500 ;FireGL V7350
dd (0x7140 shl 16)+VID_ATI, init_r500 ;Radeon X1600/X1550
dd (0x7141 shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7142 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7143 shl 16)+VID_ATI, init_r500 ;Radeon X1550
dd (0x7144 shl 16)+VID_ATI, init_r500 ;M54-GL
dd (0x7145 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1400
dd (0x7146 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7147 shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x7149 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714A shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714B shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714C shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1300
dd (0x714D shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x714E shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x714F shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7151 shl 16)+VID_ATI, init_r500 ;RV505
dd (0x7152 shl 16)+VID_ATI, init_r500 ;FireGL V3300
dd (0x7153 shl 16)+VID_ATI, init_r500 ;FireGL V3350
dd (0x715E shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x715F shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x7180 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7181 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x7183 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7186 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1450
dd (0x7187 shl 16)+VID_ATI, init_r500 ;Radeon X1300/X1550
dd (0x7188 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X2300
dd (0x718A shl 16)+VID_ATI, init_r500 ;Mobility Radeon X2300
dd (0x718B shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x718C shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x718D shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1450
dd (0x718F shl 16)+VID_ATI, init_r500 ;Radeon X1300
dd (0x7193 shl 16)+VID_ATI, init_r500 ;Radeon X1550
dd (0x7196 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1350
dd (0x719B shl 16)+VID_ATI, init_r500 ;FireMV 2250
dd (0x719F shl 16)+VID_ATI, init_r500 ;Radeon X1550 64-bit
dd (0x71C0 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C1 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71C2 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C3 shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71C4 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5200
dd (0x71C5 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1600
dd (0x71C6 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71C7 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x71CD shl 16)+VID_ATI, init_r500 ;Radeon X1600
dd (0x71CE shl 16)+VID_ATI, init_r500 ;Radeon X1300 XT/X1600 Pro
dd (0x71D2 shl 16)+VID_ATI, init_r500 ;FireGL V3400
dd (0x71D4 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5250
dd (0x71D5 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700
dd (0x71D6 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700 XT
dd (0x71DA shl 16)+VID_ATI, init_r500 ;FireGL V5200
dd (0x71DE shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1700
dd (0x7200 shl 16)+VID_ATI, init_r500 ;Radeon X2300HD
dd (0x7210 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2300
dd (0x7211 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2300
dd (0x7240 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7243 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7244 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7245 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7246 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7247 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7248 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7249 shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724A shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724B shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724C shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724D shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x724E shl 16)+VID_ATI, init_r500 ;AMD Stream Processor
dd (0x724F shl 16)+VID_ATI, init_r500 ;Radeon X1900
dd (0x7280 shl 16)+VID_ATI, init_r500 ;Radeon X1950
dd (0x7281 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7283 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7284 shl 16)+VID_ATI, init_r500 ;Mobility Radeon X1900
dd (0x7287 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7288 shl 16)+VID_ATI, init_r500 ;Radeon X1950 GT
dd (0x7289 shl 16)+VID_ATI, init_r500 ;RV570
dd (0x728B shl 16)+VID_ATI, init_r500 ;RV570
dd (0x728C shl 16)+VID_ATI, init_r500 ;ATI FireGL V7400
dd (0x7290 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x7291 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x7293 shl 16)+VID_ATI, init_r500 ;Radeon X1650
dd (0x7297 shl 16)+VID_ATI, init_r500 ;RV560
dd (0x791E shl 16)+VID_ATI, init_r500 ;Radeon X1200
dd (0x791F shl 16)+VID_ATI, init_r500 ;Radeon X1200
dd (0x793F shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200
dd (0x7941 shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200
dd (0x7942 shl 16)+VID_ATI, init_r500 ;Radeon Xpress 1200 (M)
dd (0x796C shl 16)+VID_ATI, init_r500 ;RS740
dd (0x796D shl 16)+VID_ATI, init_r500 ;RS740M
dd (0x796E shl 16)+VID_ATI, init_r500 ;ATI Radeon 2100 RS740
dd (0x796F shl 16)+VID_ATI, init_r500 ;RS740M
dd (0x9400 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9401 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9402 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 XT
dd (0x9403 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 Pro
dd (0x9405 shl 16)+VID_ATI, init_r500 ;Radeon HD 2900 GT
dd (0x940A shl 16)+VID_ATI, init_r500 ;FireGL V8650
dd (0x940B shl 16)+VID_ATI, init_r500 ;FireGL V8600
dd (0x940F shl 16)+VID_ATI, init_r500 ;FireGL V7600
dd (0x94C0 shl 16)+VID_ATI, init_r500 ;RV610
dd (0x94C1 shl 16)+VID_ATI, init_r500 ;Radeon HD 2400 XT
dd (0x94C3 shl 16)+VID_ATI, init_r500 ;Radeon HD 2400 Pro
dd (0x94C4 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2400 PRO AGP
dd (0x94C5 shl 16)+VID_ATI, init_r500 ;FireGL V4000
dd (0x94C6 shl 16)+VID_ATI, init_r500 ;RV610
dd (0x94C7 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2350
dd (0x94C8 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2400 XT
dd (0x94C9 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2400
dd (0x94CB shl 16)+VID_ATI, init_r500 ;ATI RADEON E2400
dd (0x94CC shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2400
dd (0x9500 shl 16)+VID_ATI, init_r500 ;RV670
dd (0x9501 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3870
dd (0x9504 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3850
dd (0x9505 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3850
dd (0x9506 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3850 X2
dd (0x9507 shl 16)+VID_ATI, init_r500 ;RV670
dd (0x9508 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3870
dd (0x9509 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3870 X2
dd (0x950F shl 16)+VID_ATI, init_r500 ;ATI Radeon HD3870 X2
dd (0x9511 shl 16)+VID_ATI, init_r500 ;ATI FireGL V7700
dd (0x9515 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3850 AGP
dd (0x9517 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3960
dd (0x9519 shl 16)+VID_ATI, init_r500 ;FireStream 9170
dd (0x9580 shl 16)+VID_ATI, init_r500 ;RV630
dd (0x9581 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2600
dd (0x9583 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 2600 XT
dd (0x9586 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 XT AGP
dd (0x9587 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 Pro AGP
dd (0x9588 shl 16)+VID_ATI, init_r500 ;Radeon HD 2600 XT
dd (0x9589 shl 16)+VID_ATI, init_r500 ;Radeon HD 2600 Pro
dd (0x958A shl 16)+VID_ATI, init_r500 ;Gemini RV630
dd (0x958B shl 16)+VID_ATI, init_r500 ;Gemini ATI Mobility Radeon HD 2600 XT
dd (0x958C shl 16)+VID_ATI, init_r500 ;FireGL V5600
dd (0x958D shl 16)+VID_ATI, init_r500 ;FireGL V3600
dd (0x958E shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 2600 LE
dd (0x958F shl 16)+VID_ATI, init_r500 ;ATI Mobility FireGL Graphics Processor
dd (0x9590 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x9591 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3650
dd (0x9593 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3670
dd (0x9595 shl 16)+VID_ATI, init_r500 ;Mobility FireGL V5700
dd (0x9596 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3650 AGP
dd (0x9597 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x9598 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3670
dd (0x9599 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3600 Series
dd (0x959B shl 16)+VID_ATI, init_r500 ;Mobility FireGL Graphics Processor
dd (0x95C0 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3470
dd (0x95C2 shl 16)+VID_ATI, init_r500 ;ATI Mobility Radeon HD 3430 (M82)
dd (0x95C4 shl 16)+VID_ATI, init_r500 ;Mobility Radeon HD 3400 Series (M82)
dd (0x95C5 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3450
dd (0x95C7 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3430
dd (0x95CC shl 16)+VID_ATI, init_r500 ;Fire PRO Professional Graphics ASIC
dd (0x95CD shl 16)+VID_ATI, init_r500 ;ATI FireMV 2450
dd (0x95CE shl 16)+VID_ATI, init_r500 ;ATI FireMV 2260
dd (0x95CF shl 16)+VID_ATI, init_r500 ;ATI FireMV 2260
dd (0x9610 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3200 Graphics
dd (0x9611 shl 16)+VID_ATI, init_r500 ;ATI Radeon 3100 Graphics
dd (0x9612 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3200 Graphics
dd (0x9613 shl 16)+VID_ATI, init_r500 ;ATI Radeon 3100 Graphics
dd (0x9614 shl 16)+VID_ATI, init_r500 ;ATI Radeon HD 3300 Graphics
dd (0x9440 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4800 Series
dd (0x9441 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4870 X2
dd (0x9442 shl 16)+VID_ATI, init_r500 ;ATI Radeon 4800 Series
dd (0x9444 shl 16)+VID_ATI, init_r500 ;Everest ATI FirePro Graphics Accelerator
dd (0x9446 shl 16)+VID_ATI, init_r500 ;K2 ATI FirePro Graphics Accelerator
dd (0x944E shl 16)+VID_ATI, init_r500 ;RV770
dd (0x9456 shl 16)+VID_ATI, init_r500 ;Denali ATI FirePro Graphics
dd (0x791E shl 16)+VID_ATI, init_r500 ;RS690 X1200
 
dd (0x7140 shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x7142 shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x7146 shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x714D shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x714E shl 16)+VID_ATI, init_r500 ;RV515 X1300
 
dd (0x7183 shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x7187 shl 16)+VID_ATI, init_r500 ;RV515 X1300
dd (0x718F shl 16)+VID_ATI, init_r500 ;RV515 X1300
 
dd (0x7143 shl 16)+VID_ATI, init_r500 ;RV515 X1550
dd (0x7147 shl 16)+VID_ATI, init_r500 ;RV515 X1550
dd (0x715F shl 16)+VID_ATI, init_r500 ;RV515 X1550
dd (0x7193 shl 16)+VID_ATI, init_r500 ;RV515 X1550
dd (0x719F shl 16)+VID_ATI, init_r500 ;RV515 X1550
 
dd (0x71C0 shl 16)+VID_ATI, init_r500 ;RV530 X1600
dd (0x71C1 shl 16)+VID_ATI, init_r500 ;RV535 X1650
dd (0x71C2 shl 16)+VID_ATI, init_r500 ;RV530 X1600
dd (0x71C3 shl 16)+VID_ATI, init_r500 ;RV535 X1600
dd (0x71C6 shl 16)+VID_ATI, init_r500 ;RV530 X1600
dd (0x71C7 shl 16)+VID_ATI, init_r500 ;RV534 X1650
 
dd (0x7181 shl 16)+VID_ATI, init_r500 ;RV515 X1600
dd (0x71CD shl 16)+VID_ATI, init_r500 ;RV530 X1600
 
dd (0x7291 shl 16)+VID_ATI, init_r500 ;R580 X1650
dd (0x7293 shl 16)+VID_ATI, init_r500 ;R580 X1650
 
dd (0x7100 shl 16)+VID_ATI, init_r500 ;RV520 X1800
dd (0x7109 shl 16)+VID_ATI, init_r500 ;RV520 X1800
dd (0x710A shl 16)+VID_ATI, init_r500 ;RV520 X1800 GTO
 
dd (0x7249 shl 16)+VID_ATI, init_r500 ;RV580 X1900
dd (0x724B shl 16)+VID_ATI, init_r500 ;RV580 X1900 GT
 
dd (0x7240 shl 16)+VID_ATI, init_r500 ;RV580 X1950
dd (0x7244 shl 16)+VID_ATI, init_r500 ;RV580 X1950
dd (0x7248 shl 16)+VID_ATI, init_r500 ;RV580 X1950
 
dd (0x7288 shl 16)+VID_ATI, init_r500 ;R580 X1950 GT
dd (0x7280 shl 16)+VID_ATI, init_r500 ;R580 X1950 PRO
 
dd (0x94C3 shl 16)+VID_ATI, init_r500 ;RV610 HD 2400 PRO
dd (0x94C1 shl 16)+VID_ATI, init_r500 ;RV610 HD 2400 XT
 
dd (0x9589 shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 PRO
dd (0x958A shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 X2
dd (0x9588 shl 16)+VID_ATI, init_r500 ;RV630 HD 2600 XT
 
dd (0x9403 shl 16)+VID_ATI, init_r500 ;R600 HD 2900 PRO
dd (0x9409 shl 16)+VID_ATI, init_r500 ;R600 HD 2900 XT
 
 
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
/kernel/branches/kolibri_pe/drivers/sb16/README.TXT
File deleted
\ No newline at end of file
/kernel/branches/kolibri_pe/drivers/r500hw.inc
5,10 → 5,6
The below code is a rework from code in
xf86-video-radeonhd/src/r5xx_accel.c, xf86-video-radeonhd/src/r5xx_xaa.c
 
git://anongit.freedesktop.org/git/nouveau/xf86-video-radeonhd
git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati
 
 
Copyright 2008 Luc Verhaegen <lverhaegen@novell.com>
Copyright 2008 Matthias Hopf <mhopf@novell.com>
Copyright 2008 Egbert Eich <eich@novell.com>
666,7 → 662,7
or edx, [rhd.control]
or edx, (R5XX_GMC_BRUSH_SOLID_COLOR or R5XX_GMC_SRC_DATATYPE_COLOR)
 
; Save for later clipping
; Save for later clipping */
mov [rhd.control_saved], edx
 
mov eax, 4
/kernel/branches/kolibri_pe/include/pe.h
46,10 → 46,6
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
 
#define IMAGE_FILE_DLL 0x2000
 
#define IMAGE_FILE_MACHINE_I386 0x014c /* Intel 386 or later processors
and compatible processors */
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
196,7 → 192,6
 
#define MakePtr( cast, ptr, addValue ) (cast)( (addr_t)(ptr) + (addr_t)(addValue) )
 
bool validate_pe(void *raw, size_t raw_size, bool is_exec);
 
dll_t * find_dll(link_t *list, const char *name);
 
203,6 → 198,6
 
md_t* __fastcall load_image(const char *path);
 
void create_image(addr_t img_base, addr_t raw, bool force_clear) asm ("CreateImage");
void __export create_image(addr_t img_base, addr_t image) asm ("CreateImage");
 
 
/kernel/branches/kolibri_pe/kernel.asm
4314,30 → 4314,6
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol edx, 16
.forced:
cmp esi, 1
jnz @f
push edi
mov eax, [edi+4]
sub eax, [edi]
push eax
push dword [edi]
push 0ffffff80h
mov edi, esp
call put_mono_image
add esp, 12
pop edi
ret
@@:
cmp esi, 4
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_4bit_image
pop eax
pop edi
ret
@@:
push ebp esi ebp
cmp esi, 8
jnz @f
4345,12 → 4321,6
mov esi, putimage_init8bpp
jmp sys_putimage_bpp
@@:
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
mov esi, putimage_init15bpp
jmp sys_putimage_bpp
@@:
cmp esi, 16
jnz @f
mov ebp, putimage_get16bpp
4372,28 → 4342,15
pop ebp esi ebp
ret
 
put_mono_image:
push ebp esi ebp
mov ebp, putimage_get1bpp
mov esi, putimage_init1bpp
jmp sys_putimage_bpp
put_4bit_image:
push ebp esi ebp
mov ebp, putimage_get4bpp
mov esi, putimage_init4bpp
jmp sys_putimage_bpp
 
putimage_init24bpp:
lea eax, [eax*3]
putimage_init8bpp:
ret
 
align 16
putimage_get24bpp:
mov eax, [esi]
add esi, 3
ret 4
align 16
putimage_get8bpp:
movzx eax, byte [esi]
push edx
4403,79 → 4360,17
inc esi
ret 4
 
putimage_init1bpp:
add eax, ecx
push ecx
add eax, 7
add ecx, 7
shr eax, 3
shr ecx, 3
sub eax, ecx
pop ecx
ret
align 16
putimage_get1bpp:
push edx
mov edx, [esp+8]
mov al, [edx]
add al, al
jnz @f
lodsb
adc al, al
@@:
mov [edx], al
sbb eax, eax
and eax, [edx+8]
add eax, [edx+4]
pop edx
ret 4
 
putimage_init4bpp:
add eax, ecx
push ecx
add ecx, 1
add eax, 1
shr ecx, 1
shr eax, 1
sub eax, ecx
pop ecx
ret
align 16
putimage_get4bpp:
push edx
mov edx, [esp+8]
add byte [edx], 80h
jc @f
movzx eax, byte [edx+1]
mov edx, [edx+4]
and eax, 0x0F
mov eax, [edx+eax*4]
pop edx
ret 4
@@:
movzx eax, byte [esi]
add esi, 1
mov [edx+1], al
shr eax, 4
mov edx, [edx+4]
mov eax, [edx+eax*4]
pop edx
ret 4
 
putimage_init32bpp:
shl eax, 2
ret
align 16
putimage_get32bpp:
lodsd
ret 4
 
putimage_init15bpp:
putimage_init16bpp:
add eax, eax
ret
align 16
putimage_get15bpp:
putimage_get16bpp:
; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000
push ecx edx
movzx eax, word [esi]
4491,27 → 4386,8
or eax, ecx
or eax, edx
pop edx ecx
ret 4
ret
 
align 16
putimage_get16bpp:
; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x3F shl 5
and edx, 0x1F shl 11
shl eax, 3
shl ecx, 5
shl edx, 8
or eax, ecx
or eax, edx
pop edx ecx
ret 4
 
; eax x beginning
; ebx y beginning
; ecx x end
/kernel/branches/kolibri_pe/makefile
46,7 → 46,6
include/link.h \
include/core.h \
include/mm.h \
include/pe.h \
include/slab.h
 
PE_OBJS = $(patsubst %.s, bin/%.obj, $(patsubst %.asm, bin/%.obj,\
/kernel/branches/kolibri_pe/fs/fs_lfn.inc
432,12 → 432,11
push ebx
 
call _sys_exec
mov [image_of_eax], eax
add esp, 12
mov [image_of_eax], eax
 
ret
 
 
 
; handlers for devices
; in: ecx = 0 => query virtual directory /xxx
; in: ecx = partition number
/kernel/branches/kolibri_pe/video/vesa12.inc
880,14 → 880,6
 
add edi,[BytesPerScanLine]
add esi,[esp+32]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
@@:
dec ebx
jnz newpi12
 
953,14 → 945,6
pop edi
 
add edi,[BytesPerScanLine]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
@@:
dec ebx
jnz newpi3212
 
/kernel/branches/kolibri_pe/video/vesa20.inc
163,8 → 163,7
mov [putimg.real_sy], ebx
; line increment
mov eax, [putimg.image_sx]
mov ecx, [putimg.real_sx]
sub eax, ecx
sub eax, [putimg.real_sx]
;; imul eax, [putimg.source_bpp]
; lea eax, [eax + eax * 2]
call esi
177,6 → 176,7
mov [putimg.winmap_newline], eax
; screen new line increment
mov eax, [BytesPerScanLine]
mov ecx, [putimg.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
232,14 → 232,6
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
273,14 → 265,6
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
/kernel/branches/kolibri_pe/network/tcp.inc
15,7 → 15,6
;; v0.6 : Added reset handling in the established state ;;
;; Added a timer per socket to allow delays when ;;
;; rx window gets below 1KB ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
31,16 → 30,9
TCB_CLOSE_WAIT equ 7
TCB_CLOSING equ 8
TCB_LAST_ACK equ 9
TCB_TIMED_WAIT equ 10
TCB_TIME_WAIT equ 10
TCB_CLOSED equ 11
 
TH_FIN = 0x01
TH_SYN = 0x02
TH_RST = 0x04
TH_PUSH = 0x08
TH_ACK = 0x10
TH_URG = 0x20
 
TWOMSL equ 10 ; # of secs to wait before closing socket
 
TCP_RETRIES equ 5 ; Number of times to resend a packet
110,50 → 102,62
; when the TCB timer expires
;
;***************************************************************************
 
proc tcp_tcb_handler stdcall uses ebx
tcp_tcb_handler:
; scan through all the sockets, decrementing active timers
 
mov ebx, net_sockets
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
cmp [ebx + SOCKET.NextPtr], 0
je .exit
DEBUGF 1, "K : sockets:\n"
tth1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + 32], dword 0
jne tth2
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .exit
tth1a:
cmp [eax + sockets + 72], dword 0
jne tth4
 
DEBUGF 1, "K : %x: %x-%x-%x-%u\n", ebx, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
loop tth1
ret
 
cmp [ebx + SOCKET.TCBTimer], 0
jne .decrement_tcb
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .decrement_wnd
jmp .next_socket
 
.decrement_tcb:
tth2:
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
dec [ebx + SOCKET.TCBTimer]
jnz .next_socket
pusha
dec dword [eax + sockets + 32]
cmp [eax + sockets + 32], dword 0
jne tth3
 
cmp [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
jne .next_socket
cmp [eax + sockets + 28], dword TCB_TIME_WAIT
jne tth3
 
push [ebx + SOCKET.PrevPtr]
stdcall net_socket_free, ebx
pop ebx
jmp .next_socket
; OK, delete socket
mov edi, eax
add edi, sockets
 
.decrement_wnd:
xor eax, eax
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
 
tth3:
popa
 
jmp tth1a
 
loop tth1
ret
 
; TODO - prove it works!
dec [ebx + SOCKET.wndsizeTimer]
jmp .next_socket
tth4:
dec dword [eax + sockets + 72]
loop tth1
ret
 
.exit:
 
 
 
tth_exit:
ret
endp
 
 
;***************************************************************************
165,8 → 169,7
; This is a kernel function, called by stack_handler
;
;***************************************************************************
 
proc tcp_tx_handler stdcall
tcp_tx_handler:
; decrement all resend buffers timers. If they
; expire, queue them for sending, and restart the timer.
; If the retries counter reach 0, delete the entry
174,60 → 177,63
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
tth001:
cmp ecx, NUMRESENDENTRIES
je .exit ; None left
;cmp [esi], byte 0xFF ; XTODO: 0xff -> 0
cmp dword[esi + 4], 0
jne @f ; found one
je tth003 ; None left
cmp [esi], byte 0xFF
jne tth002 ; found one
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp tth001
 
@@: ; we have one. decrement it's timer by 1
tth002:
; we have one. decrement it's timer by 1
dec word[esi + 2]
jz @f
mov ax, [esi+2]
cmp ax, 0
je tth002a
inc ecx
add esi, 8
jmp .next_resendq ; Timer not zero, so move on
add esi, 4
jmp tth001 ; Timer not zero, so move on
 
@@:
;mov bl, 0xff ; XTODO: bl -> ebx, 0xff -> 0
xor ebx, ebx
tth002a:
mov bl, 0xff
; restart timer, and decrement retries
; After the first resend, back of on next, by a factor of 5
mov [esi + 2], word TCP_TIMEOUT * 5
dec byte[esi + 1]
jnz @f
mov al, [esi+1]
cmp al, 0
jne tth004
 
; retries now 0, so delete from queue
;xchg [esi], bl ; XTODO: bl -> ebx
xchg [esi + 4], ebx
xchg [esi], bl
tth004:
 
@@: ; resend packet
pushad
; resend packet
pusha
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
jne .tth004z
jne tth004z
 
; TODO - try again in 10ms.
;cmp bl, 0xff ; XTODO: 0xff -> 0
test ebx, ebx
jnz @f
;mov [esi], bl ; XTODO: bl -> ebx
mov [esi + 4], ebx
cmp bl, 0xff
jne tth004za
mov [esi], bl
 
@@: ; Mark it to expire in 10ms - 1 tick
mov byte[esi + 1], 1
mov word[esi + 2], 1
jmp .tth005
tth004za:
; Mark it to expire in 10ms - 1 tick
mov [esi+1], byte 1
mov [esi+2], word 1
jmp tth005
 
.tth004z:
tth004z:
; we have a buffer # in ax
 
push eax ecx
push eax
push ecx
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
235,19 → 241,20
; we have the buffer address in eax
mov edi, eax
pop ecx
; get resend data address
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov esi, resendBuffer
@@: add esi, IPBUFFSIZE
loop @b
mov esi, resendBuffer - IPBUFFSIZE
tth004a:
add esi, IPBUFFSIZE
loop tth004a
 
; we have resend buffer location in esi
mov ecx, IPBUFFSIZE
 
; copy data across
push edi
cld
rep movsb
pop edi
 
; queue packet
 
256,27 → 263,30
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
cmp edx, [edi + IP_PACKET.DestinationAddress]
jne .not_local
mov ecx, [ edi + 16 ]
cmp edx, ecx
jne tth004b
mov eax, IPIN_QUEUE
 
.not_local:
tth004b:
pop ebx
 
call queue
 
.tth005:
popad
 
tth005:
popa
 
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp tth001
 
.exit:
tth003:
ret
endp
 
 
 
 
;***************************************************************************
; Function
; tcp_rx
289,8 → 299,7
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
 
proc tcp_rx stdcall uses ebx
tcp_rx:
; The process is as follows.
; Look for a socket with matching remote IP, remote port, local port
; if not found, then
309,38 → 318,28
; IP Packet SA = Remote IP
; IP Packet TCP Source Port = remote Port
 
mov ebx, net_sockets
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
ss1:
sub eax, SOCKETBUFFSIZE
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst1 ; different - try next socket
 
.next_socket.1:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.1.exit
movzx ebx, word [edx + 20] ; get the source port from the TCP hdr
cmp [eax + sockets + 20], bx ; compare with socket's remote port
jnz nxttst1 ; different - try next socket
 
cmp [ebx + SOCKET.Status], SOCK_OPEN
jne .next_socket.1
 
; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst1 ; different - try next socket
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
 
mov ax, [edx + 20 + TCP_PACKET.SourcePort] ; get the source port from the TCP hdr
cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port
jne .next_socket.1 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
jmp tcprx_001
 
.next_socket.1.exit:
nxttst1:
loop ss1 ; Return back if no match
 
; If we got here, there was no match
; Look for a socket where
348,37 → 347,29
; IP Packet SA = Remote IP
; socket remote Port = 0
 
mov ebx, net_sockets
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
.next_socket.2:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.2.exit
ss2:
sub eax, SOCKETBUFFSIZE
 
cmp [ebx + SOCKET.Status], SOCK_OPEN
jne .next_socket.2
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst2 ; different - try next socket
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.2 ; different - try next socket
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
 
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0
jne .next_socket.2 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
jmp tcprx_001
 
.next_socket.2.exit:
nxttst2:
loop ss2 ; Return back if no match
 
; If we got here, there was no match
; Look for a socket where
386,71 → 377,49
; socket Remote IP = 0
; socket remote Port = 0
 
mov ebx, net_sockets
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
.next_socket.3:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.3.exit
ss3:
sub eax, SOCKETBUFFSIZE
 
cmp [ebx + SOCKET.Status], SOCK_OPEN
jne .next_socket.3
movzx ebx, word [edx + 22] ; get destination port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst3 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst3 ; different - try next socket
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get destination port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.3 ; different - try next socket
mov ebx, 0
cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0
jnz nxttst3 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP]
 
cmp [ebx + SOCKET.RemoteIP], 0 ; only match a socket remote IP of 0
jne .next_socket.3 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
 
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0
jne .next_socket.3 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
jmp tcprx_001
 
.next_socket.3.exit:
nxttst3:
loop ss3 ; Return back if no match
 
; If we got here, we need to reject the packet
inc dword [dumped_rx_count]
jmp tcprx_exit
 
DEBUGF 1, "K : tcp_rx - dumped\n"
DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2
; mov ebx, net_sockets
;
; .next_socket.4:
; mov ebx, [ebx + SOCKET.NextPtr]
; or ebx, ebx
; jz .next_socket.4.exit
; DEBUGF 1, "K : %x: %x-%x-%x-%u\n", ebx, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
; jne .next_socket.4
;
; .next_socket.4.exit:
inc [dumped_rx_count]
jmp .exit
 
.change_state:
 
tcprx_001:
; We have a valid socket/TCB, so call the TCB State Machine for that skt.
; socket is pointed to by ebx
; IP packet is pointed to by edx
; socket is pointed to by [eax + sockets]
; IP packet is pointed to by [edx]
; IP buffer number is on stack ( it will be popped at the end)
call tcpStateMachine
 
stdcall tcpStateMachine, ebx
 
.exit:
tcprx_exit:
pop eax
call freeBuff
 
ret
endp
 
 
 
;***************************************************************************
; Function
; buildTCPPacket
465,8 → 434,7
; Transmit buffer number in eax
;
;***************************************************************************
 
proc build_tcp_packet stdcall, sockAddr:DWORD
buildTCPPacket:
push ecx ; Save data length
 
; convert buffer pointer eax to the absolute address
476,68 → 444,82
 
mov edx, eax
 
mov [edx + 20 + TCP_PACKET.Flags], bl ; TCP flags
mov [edx + 33], bl ; TCP flags
 
mov ebx, [sockAddr]
mov ebx, [sktAddr]
 
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header ( some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_PACKET.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_PACKET.DestinationAddress], eax
mov eax, [ebx + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
 
mov [edx + IP_PACKET.VersionAndIHL], 0x45
mov [edx + IP_PACKET.TypeOfService], 0
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
 
pop eax ; Get the TCP data length
push eax
 
add eax, 20 + 20 ; add IP header and TCP header lengths
rol ax, 8
mov [edx + IP_PACKET.TotalLength], ax
mov [edx + IP_PACKET.Identification], 0
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_PACKET.TimeToLive], 0x20
mov [edx + IP_PACKET.Protocol], PROTOCOL_TCP
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 6 ; TCP protocol
mov [edx + 9], al
 
; Checksum left unfilled
mov [edx + IP_PACKET.HeaderChecksum], 0
xor ax, ax
mov [edx + 10], ax
 
; Fill in the TCP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
mov [edx + 20 + TCP_PACKET.SourcePort], ax ; Local Port
mov ax, [ebx + 12]
mov [edx + 20], ax ; Local Port
 
mov ax, [ebx + SOCKET.RemotePort]
mov [edx + 20 + TCP_PACKET.DestinationPort], ax ; desitination Port
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax ; desitination Port
 
; Checksum left unfilled
mov [edx + 20 + TCP_PACKET.Checksum], 0
xor ax, ax
mov [edx + 20 + 16], ax
 
; sequence number
mov eax, [ebx + SOCKET.SND_NXT]
mov [edx + 20 + TCP_PACKET.SequenceNumber], eax
mov eax, [ebx + 48]
mov [edx + 20 + 4], eax
 
; ack number
mov eax, [ebx + SOCKET.RCV_NXT]
mov [edx + 20 + TCP_PACKET.AckNumber], eax
mov eax, [ebx + 56]
mov [edx + 20 + 8], eax
 
; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
; 768 bytes seems better
mov [edx + 20 + TCP_PACKET.Window], 0x0003
mov ax, 0x0003
mov [edx + 20 + 14], ax
 
; Urgent pointer (0)
mov [edx + 20 + TCP_PACKET.UrgentPointer], 0
mov ax, 0
mov [edx + 20 + 18], ax
 
; data offset ( 0x50 )
mov [edx + 20 + TCP_PACKET.DataOffset], 0x50
mov al, 0x50
mov [edx + 20 + 12], al
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
 
cmp ebx, 0
jz @f
jz btp_001
 
mov edi, edx
add edi, 40
544,21 → 526,24
cld
rep movsb ; copy the data across
 
@@: ; we have edx as IPbuffer ptr.
btp_001:
; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_PACKET.SourceAddress]
mov eax, [edx + 12]
mov [pseudoHeader], eax
mov eax, [edx + IP_PACKET.DestinationAddress]
mov eax, [edx + 16]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
mov ax, 0x0600 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 20
mov [pseudoHeader + 10], bh
mov [pseudoHeader + 11], bl
mov eax, ebx
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
 
mov eax, pseudoHeader
mov [checkAdd1], eax
mov word[checkSize1], 12
mov [checkSize1], word 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
569,59 → 554,94
 
; store it in the TCP checksum ( in the correct order! )
mov ax, [checkResult]
rol ax, 8
mov [edx + 20 + TCP_PACKET.Checksum], ax
 
mov [edx + 20 + 16], ah
mov [edx + 20 + 17], al
 
; Fill in the IP header checksum
GET_IHL eax, edx ; get IP-Header length
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size
rol ax, 8
mov [edx + IP_PACKET.HeaderChecksum], ax
 
mov [edx + 10], ah
mov [edx + 11], al
 
ret
endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
proc inc_inet_esi stdcall
inc_inet_esi:
push eax
mov eax, [esi]
bswap eax
inc eax
bswap eax
mov [esi], eax
add esi, 3
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
 
iie_exit:
pop eax
ret
endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
; by the value in ecx
proc add_inet_esi stdcall
add_inet_esi:
push eax
mov eax, [esi]
bswap eax
 
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
add eax, ecx
bswap eax
mov [esi], eax
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
pop eax
ret
endp
 
 
iglobal
TCBStateHandler dd \
stateTCB_LISTEN, \
stateTCB_SYN_SENT, \
stateTCB_SYN_RECEIVED, \
stateTCB_ESTABLISHED, \
stateTCB_FIN_WAIT_1, \
stateTCB_FIN_WAIT_2, \
stateTCB_CLOSE_WAIT, \
stateTCB_CLOSING, \
stateTCB_LAST_ACK, \
stateTCB_TIME_WAIT, \
stateTCB_CLOSED
TCBStateHandler:
dd stateTCB_LISTEN
dd stateTCB_SYN_SENT
dd stateTCB_SYN_RECEIVED
dd stateTCB_ESTABLISHED
dd stateTCB_FIN_WAIT_1
dd stateTCB_FIN_WAIT_2
dd stateTCB_CLOSE_WAIT
dd stateTCB_CLOSING
dd stateTCB_LAST_ACK
dd stateTCB_TIME_WAIT
dd stateTCB_CLOSED
endg
 
;***************************************************************************
633,186 → 653,211
; This is a kernel function, called by tcp_rx
;
; IP buffer address given in edx
; Socket/TCB address in ebx
; Socket/TCB address in [eax + sockets]
;
; The IP buffer will be released by the caller
;***************************************************************************
tcpStateMachine:
mov ebx, sockets
add ebx, eax
mov [sktAddr], ebx
 
proc tcpStateMachine stdcall, sockAddr:DWORD
; as a packet has been received, update the TCB timer
mov [ebx + SOCKET.TCBTimer], TWOMSL
mov ecx, TWOMSL
mov [ebx + 32], ecx
 
; If the received packet has an ACK bit set,
; remove any packets in the resend queue that this
; received packet acknowledges
pushad
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .call_handler ; No ACK, so no data yet
pusha
mov cl, [edx + 33]
and cl, 0x10
cmp cl, 0x10
jne tsm001 ; No ACK, so no data yet
 
; get skt number in eax
stdcall net_socket_addr_to_num, ebx
 
; get skt number in al
shr eax, 12
 
; The ack number is in [edx + 28], inet format
; skt in eax
; skt in al
 
mov esi, resendQ
xor ecx, ecx
mov ecx, 0
 
.next_resendq:
t001:
cmp ecx, NUMRESENDENTRIES
je .call_handler ; None left
;cmp [esi], al ; XTODO: al -> eax
cmp [esi + 4], eax
je @f ; found one
je t003 ; None left
cmp [esi], al
je t002 ; found one
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp t001
 
@@: ; Can we delete this buffer?
t002: ; Can we delete this buffer?
 
; If yes, goto @@. No, goto .next_resendq
; If yes, goto t004. No, goto t001
; Get packet data address
 
push ecx
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
imul edi, ecx, IPBUFFSIZE
add edi, resendBuffer
mov edi, resendBuffer - IPBUFFSIZE
t002a:
add edi, IPBUFFSIZE
loop t002a
 
; we have dest buffer location in edi. incoming packet in edx.
; Get this packets sequence number
; preserve al, ecx, esi, edx
mov ecx, [edi + 20 + TCP_PACKET.SequenceNumber]
bswap ecx
movzx ebx, word[edi + 2]
xchg bl, bh
 
mov cl, [edi + 24]
shl ecx, 8
mov cl, [edi + 25]
shl ecx, 8
mov cl, [edi + 26]
shl ecx, 8
mov cl, [edi + 27]
movzx ebx, byte [edi + 3]
mov bh, [edi + 2]
sub ebx, 40
add ecx, ebx ; ecx is now seq# of last byte +1, intel format
 
; get recievd ack #, in intel format
mov ebx, [edx + 20 + TCP_PACKET.AckNumber]
bswap ebx
mov bl, [edx + 28]
shl ebx, 8
mov bl, [edx + 29]
shl ebx, 8
mov bl, [edx + 30]
shl ebx, 8
mov bl, [edx + 31]
 
cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que
; DANGER! need to handle case that we have just
; passed the 2**32, and wrapped round!
pop ecx
jae @f ; if rx > old, delete old
 
jae t004 ; if rx > old, delete old
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp t001
 
;@@: mov byte[esi], 0xff ; XTODO: 0xff -> 0
@@: mov dword[esi + 4], 0
 
t004:
dec dword [arp_rx_count] ; ************ TEST ONLY!
 
mov [esi], byte 0xFF
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp t001
 
.call_handler:
popad
t003:
 
tsm001:
popa
 
; Call handler for given TCB state
mov ebx, [eax + sockets+28]
cmp ebx, TCB_LISTEN
jb tsm_exit
cmp ebx, TCB_CLOSED
ja tsm_exit
 
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_LISTEN
jb .exit
cmp eax, TCB_CLOSED
ja .exit
dec ebx
call dword [TCBStateHandler+ebx*4]
 
stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
 
.exit:
tsm_exit:
ret
endp
 
 
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
 
stateTCB_LISTEN:
; In this case, we are expecting a SYN packet
; For now, if the packet is a SYN, process it, and send a response
; If not, ignore it
 
; Look at control flags
test [edx + 20 + TCP_PACKET.Flags], TH_SYN
jz .exit
mov bl, [edx + 33]
and bl, 0x02
cmp bl, 0x02
jnz stl_exit
 
; We have a SYN. update the socket with this IP packets details,
; And send a response
 
mov eax, [edx + IP_PACKET.SourceAddress]
mov [ebx + SOCKET.RemoteIP], eax
mov ax, [edx + 20 + TCP_PACKET.SourcePort]
mov [ebx + SOCKET.RemotePort], ax
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber]
mov [ebx + SOCKET.IRS], eax
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
mov ebx, [edx + 12] ; IP source address
mov [eax + sockets + 16], ebx
mov bx, [edx + 20] ; IP source port
mov [eax + sockets + 20], bx
mov ebx, [edx + 24] ; IRS
mov [eax + sockets + 40], ebx
mov [eax + sockets + 56], ebx
mov esi, sockets
add esi, eax
add esi, 56
call inc_inet_esi ; RCV.NXT
mov eax, [ebx + SOCKET.ISS]
mov [ebx + SOCKET.SND_NXT], eax
mov ebx, [eax + sockets + 36] ; ISS
mov [eax + sockets + 48], ebx ; SND.NXT
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
je stl_exit
 
push eax
mov bl, TH_SYN + TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x12 ; SYN + ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stl_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
stl_notlocal:
; Send it.
pop ebx
call queue
 
mov esi, [sockAddr]
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
 
; increment SND.NXT in socket
add esi, SOCKET.SND_NXT
mov ebx, TCB_SYN_RECEIVED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
; increament SND.NXT in socket
add esi, 48
call inc_inet_esi
 
.exit:
stl_exit:
ret
endp
 
 
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
 
stateTCB_SYN_SENT:
; We are awaiting an ACK to our SYN, with a SYM
; Look at control flags - expecting an ACK
mov bl, [edx + 33]
and bl, 0x12
cmp bl, 0x12
jnz stss_exit
 
mov al, [edx + 20 + TCP_PACKET.Flags]
and al, TH_SYN + TH_ACK
cmp al, TH_SYN + TH_ACK
je .syn_ack
mov ebx, TCB_ESTABLISHED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
test al, TH_SYN
jz .exit
 
mov [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
push TH_SYN + TH_ACK
jmp .send
 
.syn_ack:
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED
push TH_ACK
 
.send:
; Store the recv.nxt field
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber]
mov eax, [edx + 24]
 
; Update our recv.nxt field
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
mov esi, [sktAddr]
add esi, 56
mov [esi], eax
call inc_inet_esi
 
; Send an ACK
820,174 → 865,196
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
pop ebx
je .exit
je stss_exit
 
push eax
 
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stss_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
stss_notlocal:
; Send it.
pop ebx
call queue
 
.exit:
stss_exit:
ret
endp
 
 
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
 
stateTCB_SYN_RECEIVED:
; In this case, we are expecting an ACK packet
; For now, if the packet is an ACK, process it,
; If not, ignore it
 
test [edx + 20 + TCP_PACKET.Flags], TH_RST ;xxx
jz .check_ack ;xxx
 
push [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
 
mov [ebx + SOCKET.TCBState], TCB_LISTEN ;xxx
jmp .exit ;xxx
 
.check_ack: ;xxx
; Look at control flags - expecting an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stsr_exit
 
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED
mov ebx, TCB_ESTABLISHED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
.exit:
stsr_exit:
ret
endp
 
 
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
 
stateTCB_ESTABLISHED:
; Here we are expecting data, or a request to close
; OR both...
 
; Did we receive a FIN or RST?
;xxx test [edx + 20 + TCP_PACKET.Flags], TH_FIN + TH_RST
;xxx jz .check_ack
test [edx + 20 + TCP_PACKET.Flags], TH_FIN ;xxx
jz .check_ack ;xxx
mov bl, [edx + 33]
and bl, 0x05
cmp bl, 0
je ste_chkack
 
; It was a fin or reset.
 
; Remove resend entries from the queue - I dont want to send any more data
pushad
pusha
 
; get skt #
stdcall net_socket_addr_to_num, ebx
mov ebx, [sktAddr]
sub ebx, sockets
shr ebx, 12 ; get skt #
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
ste001:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
;cmp [esi], al ; XTODO: al -> eax
cmp [esi + 4], eax
je @f ; found one
je ste003 ; None left
cmp [esi], bl
je ste002 ; found one
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp ste001
 
;@@: mov byte[esi], 0xff ; XTODO: 0xff -> 0
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
ste002:
dec dword [arp_rx_count] ; ************ TEST ONLY!
 
.last_resendq:
popad
mov [esi], byte 0xFF
jmp ste001
 
;xxx ; was it a reset?
;xxx test [edx + 20 + TCP_PACKET.Flags], TH_RST
;xxx jz @f
ste003:
popa
 
;xxx mov [ebx + SOCKET.TCBState], TCB_CLOSED
;xxx jmp .exit
; was it a reset?
mov bl, [edx + 33]
and bl, 0x04
cmp bl, 0x04
jne ste003a
 
@@: ; Send an ACK to that fin, and enter closewait state
mov esi, [sktAddr]
mov ebx, TCB_CLOSED
mov [esi + 28], ebx
jmp ste_exit
 
mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
lea esi, [ebx + SOCKET.RCV_NXT]
ste003a:
; Send an ACK to that fin, and enter closewait state
 
mov esi, [sktAddr]
mov ebx, TCB_CLOSE_WAIT
mov [esi + 28], ebx
add esi, 56
mov eax, [esi] ; save original
call inc_inet_esi
;; jmp ste_ack - NO, there may be data
 
.check_ack:
ste_chkack:
; Check that we received an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz ste_exit
 
 
; TODO - done, I think!
; First, look at the incoming window. If this is less than or equal to 1024,
; Set the socket window timer to 1. This will stop an additional packets being queued.
; Set the socket window timer to 1. This will stop an additional packets being
; queued.
; ** I may need to tweak this value, since I do not know how many packets are already queued
mov cx, [edx + 20 + TCP_PACKET.Window]
xchg cl, ch
mov ch, [edx + 34]
mov cl, [edx + 35]
cmp cx, 1024
ja @f
ja ste004
 
mov [ebx + SOCKET.wndsizeTimer], 1
mov ecx, [sktAddr]
mov [ecx+72], dword 1
 
@@: ; OK, here is the deal
ste004:
 
; OK, here is the deal
; My recv.nct field holds the seq of the expected next rec byte
; if the recevied sequence number is not equal to this, do not
; increment the recv.nxt field, do not copy data - just send a
; repeat ack.
 
; recv.nxt is in dword [edx+24], in inet format
; recv.nxt is in dword [edx+24], in inext format
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov ecx, [ebx + SOCKET.RCV_NXT]
cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
jne @f
mov ecx, [sktAddr]
add ecx, 56
 
cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT
mov ecx, [ecx]
jne stenofin
mov ecx, eax
 
@@: cmp ecx, [edx + 20 + TCP_PACKET.SequenceNumber]
jne .ack
stenofin:
cmp ecx, [edx+24]
jne ste_ack
 
 
; Read the data bytes, store in socket buffer
movzx ecx, [edx + IP_PACKET.TotalLength]
xchg cl, ch
xor ecx, ecx
mov ch, [edx + 2]
mov cl, [edx + 3]
sub ecx, 40 ; Discard 40 bytes of header
jnz .data ; Read data, if any
 
cmp ecx, 0
jnz ste_data ; Read data, if any
 
; If we had received a fin, we need to ACK it.
cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
je .ack
jmp .exit
mov esi, [sktAddr]
mov ebx, [esi + 28]
cmp ebx, TCB_CLOSE_WAIT
jz ste_ack
jnz ste_exit
 
.data:
ste_data:
push ecx
mov esi, [sktAddr]
 
add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer
add [esi + 24], ecx ; increment the count of bytes in buffer
 
mov eax, [ebx + SOCKET.PID] ; get socket owner PID
mov eax, [esi + 4] ; get socket owner PID
push eax
 
mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer
mov eax, [esi + 24] ; get # of bytes already in buffer
 
; point to the location to store the data
lea edi, [ebx + eax + SOCKETHEADERSIZE]
sub edi, ecx
add esi, eax
sub esi, ecx
add esi, SOCKETHEADERSIZE
 
add edx, 40 ; edx now points to the data
mov edi, esi
mov esi, edx
 
cld
998,75 → 1065,79
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
news:
cmp [esi], eax
je .found_pid
je foundPID1
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
jbe news
 
.found_pid:
foundPID1:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event
 
pop ecx
 
; Update our recv.nxt field
lea esi, [ebx + SOCKET.RCV_NXT]
mov esi, [sktAddr]
add esi, 56
call add_inet_esi
 
.ack:
ste_ack:
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
je ste_exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne ste_notlocal
mov eax, IPIN_QUEUE
ste_notlocal:
 
.not_local:
; Send it.
pop ebx
call queue
 
.exit:
ste_exit:
ret
endp
 
 
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
 
stateTCB_FIN_WAIT_1:
; We can either receive an ACK of a fin, or a fin
mov al, [edx + 20 + TCP_PACKET.Flags]
and al, TH_FIN + TH_ACK
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stfw1_001
 
cmp al, TH_ACK
jne @f
 
; It was an ACK
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
jmp .exit
mov esi, [sktAddr]
mov ebx, TCB_FIN_WAIT_2
mov [esi + 28], ebx
jmp stfw1_exit
 
@@: mov [ebx + SOCKET.TCBState], TCB_CLOSING
cmp al, TH_FIN
je @f
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
 
@@: lea esi, [ebx + SOCKET.RCV_NXT]
stfw1_001:
; It must be a fin then
mov esi, [sktAddr]
mov ebx, TCB_CLOSING
mov [esi + 28], ebx
add esi, 56
call inc_inet_esi
 
; Send an ACK
1073,116 → 1144,160
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
je stfw1_exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stfw1_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
stfw1_notlocal:
; Send it.
pop ebx
call queue
 
.exit:
stfw1_exit:
ret
endp
 
 
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
test [edx + 20 + TCP_PACKET.Flags], TH_FIN
jz .exit
 
stateTCB_FIN_WAIT_2:
mov esi, [sktAddr]
 
; Get data length
xor ecx, ecx
mov ch, [edx+2]
mov cl, [edx+3]
sub ecx, 40
 
mov bl, [edx + 33]
and bl, 0x01
cmp bl, 0x01
jne stfw2001
 
; Change state, as we have a fin
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
mov ebx, TCB_TIME_WAIT
mov [esi + 28], ebx
 
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi
inc ecx ; FIN is part of the sequence space
 
stfw2001:
add esi, 56
call add_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
je stfw2_exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stfw2_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
stfw2_notlocal:
; Send it.
pop ebx
call queue
 
.exit:
; Only delete the socket if we received the FIN
 
mov edx, [sktAddr]
mov bl, [edx + 33]
and bl, 0x01
cmp bl, 0x01
jne stfw2_exit
 
; mov edi, [sktAddr]
 
; delete the socket. Should really wait for 2MSL
; xor eax, eax
; mov ecx,SOCKETHEADERSIZE
; cld
; rep stosb
 
stfw2_exit:
ret
endp
 
 
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
 
stateTCB_CLOSE_WAIT:
; Intentionally left empty
; socket_close_tcp handles this
ret
endp
 
 
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
 
stateTCB_CLOSING:
; We can either receive an ACK of a fin, or a fin
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stc_exit
 
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
; It was an ACK
 
.exit:
mov edi, [sktAddr]
 
; delete the socket
xor eax, eax
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
stc_exit:
ret
endp
 
 
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
 
stateTCB_LAST_ACK:
; Look at control flags - expecting an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stla_exit
 
mov edi, [sktAddr]
 
; delete the socket
stdcall net_socket_free, ebx
; mov edi, ebx
; xor eax, eax
; mov ecx, SOCKETHEADERSIZE
; cld
; rep stosb
xor eax, eax
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
.exit:
stla_exit:
ret
endp
 
 
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
 
stateTCB_TIME_WAIT:
ret
endp
 
 
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
 
stateTCB_CLOSED:
ret
endp
/kernel/branches/kolibri_pe/network/eth_drv/drivers/forcedeth.inc
File deleted
/kernel/branches/kolibri_pe/network/eth_drv/drivers/rtl8169.inc
1,4 → 1,4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
339,7 → 339,7
 
; Define the RX Descriptor
align 256
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_RxDesc
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc
 
; Create a static buffer of size RX_BUF_SZ for each
; RX Descriptor All descriptors point to a
524,7 → 524,7
; Also adjust PCI latency timer to a reasonable value, 32.
proc adjust_pci_device
 
; DEBUGF 1,"K : adjust_pci_device\n"
DEBUGF 1,"K : adjust_pci_device\n"
 
stdcall pci_read_config_word,PCI_COMMAND
mov bx,ax
531,13 → 531,13
or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO
cmp ax,bx
je @f
; DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2
DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2
stdcall pci_write_config_word,PCI_COMMAND,ebx
@@:
stdcall pci_read_config_byte,PCI_LATENCY_TIMER
cmp al,32
jae @f
; DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al
DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al
stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32
@@:
ret
559,7 → 559,7
stdcall pci_read_config_dword,eax
or eax,eax
jz .not64
; DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n"
DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n"
add esp,4
or eax,-1
ret
572,7 → 572,7
 
proc rtl8169_init_board
 
; DEBUGF 1,"K : rtl8169_init_board\n"
DEBUGF 1,"K : rtl8169_init_board\n"
 
call adjust_pci_device
 
592,7 → 592,7
; identify config method
RTL_R32 RTL8169_REG_TxConfig
and eax,0x7c800000
; DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
mov esi,mac_info-8
@@: add esi,8
mov ecx,eax
625,9 → 625,9
jmp .match
@@:
; if unknown chip, assume array element #0, original RTL-8169 in this case
; DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
RTL_R32 RTL8169_REG_TxConfig
; DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
 
mov [rtl8169_tpc.chipset],0
 
642,7 → 642,7
 
proc rtl8169_hw_PHY_config
 
; DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
 
; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg);
 
705,7 → 705,7
jmp .exit
.not_2_or_3:
; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg);
; DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
.exit:
ret
endp
716,7 → 716,7
 
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword
 
;;; DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
 
movzx eax,[RegAddr]
shl eax,16
723,7 → 723,7
or eax,[value]
or eax,0x80000000
RTL_W32 RTL8169_REG_PHYAR,eax
stdcall udelay,1 ;;;1000
stdcall udelay,1000
 
mov ecx,2000
; Check if the RTL8169 has completed writing to the specified MII register
730,7 → 730,7
@@: RTL_R32 RTL8169_REG_PHYAR
test eax,0x80000000
jz .exit
stdcall udelay,1 ;;;100
stdcall udelay,100
loop @b
.exit:
ret
738,7 → 738,7
 
proc RTL8169_READ_GMII_REG,RegAddr:byte
 
;;; DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
 
push ecx
movzx eax,[RegAddr]
745,7 → 745,7
shl eax,16
; or eax,0x0
RTL_W32 RTL8169_REG_PHYAR,eax
stdcall udelay,1 ;;;1000
stdcall udelay,1000
 
mov ecx,2000
; Check if the RTL8169 has completed retrieving data from the specified MII register
752,7 → 752,7
@@: RTL_R32 RTL8169_REG_PHYAR
test eax,0x80000000
jnz .exit
stdcall udelay,1 ;;;100
stdcall udelay,100
loop @b
 
or eax,-1
767,7 → 767,7
 
proc rtl8169_set_rx_mode
 
; DEBUGF 1,"K : rtl8169_set_rx_mode\n"
DEBUGF 1,"K : rtl8169_set_rx_mode\n"
 
; IFF_ALLMULTI
; Too many to filter perfectly -- accept all multicasts
785,7 → 785,7
 
proc rtl8169_init_ring
 
; DEBUGF 1,"K : rtl8169_init_ring\n"
DEBUGF 1,"K : rtl8169_init_ring\n"
 
xor eax,eax
mov [rtl8169_tpc.cur_rx],eax
820,7 → 820,6
mov ecx,NUM_RX_DESC
@@: mov [esi],eax
mov [edi+rtl8169_RxDesc.buf_addr],eax
sub [edi+rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
add esi,4
add edi,sizeof.rtl8169_RxDesc
834,7 → 833,7
 
proc rtl8169_hw_start
 
; DEBUGF 1,"K : rtl8169_hw_start\n"
DEBUGF 1,"K : rtl8169_hw_start\n"
 
; Soft reset the chip
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
880,14 → 879,8
RTL_W16 0xE2,0x0000
 
MOV [rtl8169_tpc.cur_rx],0
push eax ; shurf 28.09.2008
mov eax, [rtl8169_tpc.TxDescArray] ; shurf 28.09.2008
sub eax, OS_BASE ; shurf 28.09.2008
RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray] ; shurf 28.09.2008
mov eax, [rtl8169_tpc.RxDescArray] ; shurf 28.09.2008
sub eax, OS_BASE ; shurf 28.09.2008
RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray] ; shurf 28.09.2008
pop eax ; shurf 28.09.2008
RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray]
RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray]
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
stdcall udelay,10
RTL_W32 RTL8169_REG_RxMissed,0
920,7 → 913,7
;***************************************************************************
proc rtl8169_probe
 
; DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
 
call rtl8169_init_board
 
935,7 → 928,7
inc ebx
loop @b
 
; DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2
DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2
 
; Config PHY
stdcall rtl8169_hw_PHY_config
995,7 → 988,7
;***************************************************************************
proc rtl8169_reset
 
; DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
 
mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
; Tx Desscriptor needs 256 bytes alignment
1040,7 → 1033,7
;***************************************************************************
proc rtl8169_transmit
 
; DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
 
push ecx edx esi
mov eax,MAX_ETH_FRAME_SIZE
1094,7 → 1087,6
add eax,[rtl8169_tpc.TxDescArray]
xchg eax,ebx
mov [ebx + rtl8169_TxDesc.buf_addr],eax
sub [ebx + rtl8169_TxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
 
mov eax,ecx
cmp eax,ETH_ZLEN
1118,7 → 1110,7
jnz @f
stdcall udelay,10
loop @b
; DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n"
DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n"
@@:
 
ret
1176,7 → 1168,7
add eax,-4
mov [eth_rx_data_len],ax
 
; DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax
DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax
 
push eax
mov ecx,eax
1198,10 → 1190,9
@@: mov [ebx + rtl8169_RxDesc.status],eax
 
mov [ebx + rtl8169_RxDesc.buf_addr],edx
sub [ebx + rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
jmp @f
.else:
; DEBUGF 1,"K : rtl8169_poll: Rx Error\n"
DEBUGF 1,"K : rtl8169_poll: Rx Error\n"
; FIXME: shouldn't I reset the status on an error
@@:
inc [rtl8169_tpc.cur_rx]
/kernel/branches/kolibri_pe/network/eth_drv/ethernet.inc
104,7 → 104,6
include "drivers/sis900.inc"
include "drivers/pcnet32.inc"
include "drivers/rtl8169.inc"
include "drivers/forcedeth.inc"
 
; PCICards
; ========
154,7 → 153,6
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816710ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
 
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
202,23 → 200,6
;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
 
dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller
dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
 
 
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove
endg
 
353,9 → 334,6
; All registers may be destroyed
;
;***************************************************************************
uglobal
ether_IP_handler_cnt dd ?
endg
ether_IP_handler:
mov eax, EMPTY_QUEUE
call dequeue
379,9 → 357,6
cld
rep movsd
 
; inc [ether_IP_handler_cnt]
; DEBUGF 1, "K : ether_IP_handler (%u)\n", [ether_IP_handler_cnt]
 
; And finally, place the buffer in the IPRX queue
pop ebx
mov eax, IPIN_QUEUE
468,18 → 443,16
cmp ax, ETHER_ARP
je .is_arp ; It is ARP
 
DEBUGF 1,"K : eth_rx - dumped (%u)\n", ax
inc [dumped_rx_count]
jmp .exit ; If not IP or ARP, ignore
 
.is_ip:
; DEBUGF 1,"K : eth_rx - IP packet\n"
DEBUGF 1,"K : eth_rx - IP packet\n"
inc dword [ip_rx_count]
call ether_IP_handler
jmp .exit
 
.is_arp:
; DEBUGF 1,"K : eth_rx - ARP packet\n"
DEBUGF 1,"K : eth_rx - ARP packet\n"
; At this point, the packet is still in the Ether_buffer
call arp_handler
 
/kernel/branches/kolibri_pe/network/socket.inc
77,23 → 77,21
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 76| RX Data Buffer |
; 76| RX offset from
; 76| RX Data |
; +-+-+-.......... -+
 
 
; so, define struct
struc SOCKET
{
.PrevPtr dd ?
.NextPtr dd ?
.Status dd ? ;+00 - Status ( of this buffer )
{ .Status dd ? ;+00 - Status ( of this buffer )
.PID dd ? ;+04 - Application Process ID
.LocalIP dd ? ;+08 - Local IP Address
.LocalPort dw ? ;+12 - Local Port
.UnusedL dw ? ;+14 - may be removed in future
.RemoteIP dd ? ;+16 - Remote IP Address
.RemotePort dw ? ;+20 - Remote Port
.OrigRemoteIP dd ?
.OrigRemotePort dw ?
.UnusedR dw ? ;+22 - may be removed in future
.rxDataCount dd ? ;+24 - Rx Data Count
.TCBState dd ? ;+28 - TCB STATE
.TCBTimer dd ? ;+32 - TCB Timer (seconds)
115,132 → 113,21
end virtual
 
; simple macro calcing real memory address of SOCKET struct by socket's
;macro Index2RealAddr reg
;{
; shl reg, 12
; add reg, sockets
;}
macro Index2RealAddr reg
{
shl reg, 12
add reg, sockets
}
 
;Constants
; current socket statuses
SOCK_EMPTY = 0 ; socket not in use
SOCK_OPEN = 1 ; open issued, but no data sent
SOCK_EMPTY equ 0 ; socket not in use
SOCK_OPEN equ 1 ; open issued, but no data sent
 
; TCP opening modes
SOCKET_PASSIVE equ 0
SOCKET_ACTIVE equ 1
 
proc net_socket_alloc stdcall uses ebx ecx edx edi
mov ecx, SOCKETBUFFSIZE
mov edx, PG_SW
call @mem_alloc@8
DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax
or eax, eax
jz .exit
 
push eax
mov edi, eax
mov ecx, SOCKETBUFFSIZE / 4
cld
xor eax, eax
rep stosd
pop eax
 
mov ebx, net_sockets
push [ebx + SOCKET.NextPtr]
mov [ebx + SOCKET.NextPtr], eax
mov [eax + SOCKET.PrevPtr], ebx
pop ebx
mov [eax + SOCKET.NextPtr], ebx
or ebx, ebx
jz @f
mov [ebx + SOCKET.PrevPtr], eax
 
@@: mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.PID], ebx
 
.exit:
ret
endp
 
proc net_socket_free stdcall uses ebx ecx edx, sock:DWORD
mov eax, [sock]
DEBUGF 1, "K : net_socket_free (0x%x)\n", eax
or eax, eax
jz .error
 
mov ebx, net_sockets
mov ecx, [TASK_BASE]
mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp ebx, eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
 
mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr]
mov [eax + SOCKET.NextPtr], ebx
or ebx, ebx
jz @f
mov [ebx + SOCKET.PrevPtr], eax
 
@@:
mov ecx, [sock]
call @mem_free@4
ret
 
.error:
DEBUGF 1, "K : failed\n"
ret
endp
 
proc net_socket_num_to_addr stdcall uses ebx ecx, x:DWORD
; FIXME: do real transform
mov eax, [x]
mov ebx, net_sockets
mov ecx, [TASK_BASE]
mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp ebx, eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
ret
 
.error:
xor eax, eax
ret
endp
 
proc net_socket_addr_to_num stdcall uses ebx ecx, x:DWORD
; FIXME: do real transform
mov eax, [x]
mov ebx, net_sockets
mov ecx, [TASK_BASE]
mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp ebx, eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
ret
 
.error:
xor eax, eax
ret
endp
 
;***************************************************************************
; Function
; is_localport_unused
253,26 → 140,51
; On return, eax = 1 for free, 0 for in use
;
;***************************************************************************
proc is_localport_unused stdcall
is_localport_unused:
mov al, bh
mov ah, bl
mov bx, ax
 
xchg bl, bh
mov edx, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
mov eax, 0 ; Assume the return value is 'in use'
 
xor eax, eax ; Assume the return value is 'free'
inc al
mov edx, net_sockets
ilu1:
sub edx, SOCKETBUFFSIZE
cmp [edx + sockets + SOCKET.LocalPort], bx
loopnz ilu1 ; Return back if the socket is occupied
 
.next_socket:
mov edx, [edx + SOCKET.NextPtr]
or edx, edx
jz .exit
cmp [edx + SOCKET.LocalPort], bx
jne .next_socket ; Return back if the port is not occupied
jz ilu_exit
inc eax ; return port not in use
 
dec al ; return 'in use'
ilu_exit:
ret
 
.exit:
 
 
;***************************************************************************
; Function
; get_free_socket
;
; Description
;
;***************************************************************************
get_free_socket:
push ecx
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
gfs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
loopnz gfs1 ; Return back if the socket is occupied
mov eax, ecx
pop ecx
jz gfs_exit
mov eax, 0xFFFFFFFF
 
gfs_exit:
ret
endp
 
 
;***************************************************************************
287,16 → 199,18
; return socket # in eax, -1 if none available
;
;***************************************************************************
proc socket_open stdcall
call net_socket_alloc
or eax, eax
jz .error
socket_open:
call get_free_socket
 
DEBUGF 1, "K : socket_open (0x%x)\n", eax
cmp eax, 0xFFFFFFFF
jz so_exit
 
; ax holds the socket number that is free. Get real address
push eax
Index2RealAddr eax
 
mov [eax + SOCKET.Status], SOCK_OPEN
mov [eax + SOCKET.Status], dword SOCK_OPEN
 
xchg bh, bl
mov [eax + SOCKET.LocalPort], bx
xchg ch, cl
305,18 → 219,18
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count
 
;pop eax ; Get the socket number back, so we can return it
stdcall net_socket_addr_to_num
ret
mov esi, [TASK_BASE]
mov ebx, [esi+TASKDATA.pid]
mov [eax + SOCKET.PID], ebx ; save the process ID
pop eax ; Get the socket number back, so we can return it
 
.error:
DEBUGF 1, "K : socket_open (fail)\n"
or eax, -1
so_exit:
ret
endp
 
 
 
;***************************************************************************
; Function
; socket_open_tcp
331,111 → 245,94
; return socket # in eax, -1 if none available
;
;***************************************************************************
proc socket_open_tcp stdcall
local sockAddr dd ?
socket_open_tcp:
call get_free_socket
 
cmp esi, SOCKET_PASSIVE
jne .skip_port_check
cmp eax, 0xFFFFFFFF
jz so_exit
 
push ebx
mov eax, ebx
xchg al, ah
mov ebx, net_sockets
; ax holds the socket number that is free. Get real address
push eax
Index2RealAddr eax
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .last_socket
cmp [ebx + SOCKET.TCBState], TCB_LISTEN
jne .next_socket
cmp [ebx + SOCKET.LocalPort], ax
jne .next_socket
mov [sktAddr], eax
mov [eax], dword SOCK_OPEN
 
xchg al, ah
DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx
pop ebx
jmp .error
 
.last_socket:
pop ebx
 
.skip_port_check:
call net_socket_alloc
or eax, eax
jz .error
 
DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax
 
mov [sockAddr], eax
 
; TODO - check this works!
;xxx: already 0 (intialized by net_socket_alloc)
;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer.
mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer.
 
xchg bh, bl
mov [eax + SOCKET.LocalPort], bx
; mov [eax + 12], byte bh ; Local port ( LS 16 bits )
; mov [eax + 13], byte bl ; Local port ( LS 16 bits )
 
xchg ch, cl
mov [eax + SOCKET.RemotePort], cx
mov [eax + SOCKET.OrigRemotePort], cx
; mov [eax + 20], ch ; Remote Port ( LS 16 bits )
; mov [eax + 21], cl ; Remote Port ( LS 16 bits )
 
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
mov [eax + SOCKET.OrigRemoteIP], edx
mov [eax + SOCKET.rxDataCount], dword 0
 
; Now fill in TCB state
mov ebx, TCB_LISTEN
cmp esi, SOCKET_PASSIVE
je @f
jz sot_001
mov ebx, TCB_SYN_SENT
@@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
 
sot_001:
mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
 
mov esi, [TASK_BASE]
mov ecx, [esi+TASKDATA.pid]
mov [eax + SOCKET.PID], ecx ; save the process ID
 
cmp ebx, TCB_LISTEN
je .exit
je sot_done
 
; Now, if we are in active mode, then we have to send a SYN to the specified remote port
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
je sot_done
 
push eax
 
mov bl, TH_SYN
xor ecx, ecx
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x02 ; SYN
mov ecx, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne sot_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
sot_notlocal:
; Send it.
pop ebx
call queue
 
mov esi, [sockAddr]
mov esi, [sktAddr]
 
; increment SND.NXT in socket
add esi, SOCKET.SND_NXT
add esi, 48
call inc_inet_esi
 
.exit:
mov ebx, [sockAddr]
mov [ebx + SOCKET.Status], SOCK_OPEN
;pop eax ; Get the socket number back, so we can return it
stdcall net_socket_addr_to_num, ebx
ret
sot_done:
pop eax ; Get the socket number back, so we can return it
 
.error:
DEBUGF 1, "K : socket_open_tcp (fail)\n"
or eax, -1
sot_exit:
ret
endp
 
 
 
;***************************************************************************
; Function
; socket_close
445,33 → 342,26
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
proc socket_close stdcall
DEBUGF 1, "K : socket_close (0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
socket_close:
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp ebx, NUM_SOCKETS
jae sc_exit
Index2RealAddr ebx
cmp [ebx + SOCKET.Status], dword SOCK_EMPTY
jz sc_exit
 
cmp [eax + SOCKET.Status], dword SOCK_EMPTY
jz .error
 
; Clear the socket varaibles
stdcall net_socket_free, eax
; mov edi, eax
; xor eax, eax
; mov ecx, SOCKETHEADERSIZE
; cld
; rep stosb
 
xor eax, eax
ret
mov edi, ebx
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
 
.error:
DEBUGF 1, "K : socket_close (fail)\n"
or eax, -1
sc_exit:
ret
endp
 
 
 
;***************************************************************************
; Function
; socket_close_tcp
481,9 → 371,7
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
proc socket_close_tcp stdcall
local sockAddr dd ?
DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx
socket_close_tcp:
; first, remove any resend entries
pusha
 
490,113 → 378,105
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
sct001:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
;cmp [esi], bl ; XTODO: bl -> ebx
cmp [esi + 4], ebx
je @f ; found one
je sct003 ; None left
cmp [esi], bl
je sct002 ; found one
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp sct001
 
;@@: mov byte[esi], 0xff ; XTODO: 0xff -> 0
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
sct002:
 
.last_resendq:
mov [esi], byte 0xFF
jmp sct001
 
sct003:
popa
 
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
Index2RealAddr ebx
mov [sktAddr], ebx
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp [ebx + SOCKET.Status], dword SOCK_EMPTY
jz sct_exit
 
mov ebx, eax
mov [sockAddr], eax
cmp [ebx + SOCKET.Status], SOCK_EMPTY
je .error
 
cmp [ebx + SOCKET.TCBState], TCB_LISTEN ;xxx
je .destroy_tcb ;xxx
cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT ;xxx
je .destroy_tcb ;xxx
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
je stl_exit
 
push eax
 
;xxx mov bl, TH_FIN + TH_ACK
mov bl, TH_FIN ;xxx
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
mov bl, 0x11 ; FIN + ACK
mov ecx, 0
mov esi, 0
 
mov ebx, [sockAddr]
call buildTCPPacket
 
mov ebx, [sktAddr]
 
; increament SND.NXT in socket
lea esi, [ebx + SOCKET.SND_NXT]
mov esi, 48
add esi, ebx
call inc_inet_esi
 
 
; Get the socket state
mov eax, [ebx + SOCKET.TCBState]
;xxx cmp eax, TCB_LISTEN
;xxx je .destroy_tcb
;xxx cmp eax, TCB_SYN_SENT
;xxx je .destroy_tcb
cmp eax, TCB_LISTEN
je destroyTCB
cmp eax, TCB_SYN_SENT
je destroyTCB
cmp eax, TCB_SYN_RECEIVED
je .fin_wait_1
je sct_finwait1
cmp eax, TCB_ESTABLISHED
je .fin_wait_1
je sct_finwait1
 
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
; TODO: check if it's really a TCB_CLOSE_WAIT
mov [ebx + SOCKET.TCBState], TCB_LAST_ACK
jmp .send
mov eax, TCB_LAST_ACK
mov [ebx + SOCKET.TCBState], eax
xor eax, eax
jmp sct_send
 
.fin_wait_1:
sct_finwait1:
; Send a fin, then enter finwait2 state
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
mov eax, TCB_FIN_WAIT_1
mov [ebx + SOCKET.TCBState], eax
xor eax, eax
 
.send:
sct_send:
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne sct_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
sct_notlocal:
; Send it.
pop ebx
call queue
jmp .exit
jmp sct_exit
 
.destroy_tcb:
;xxx pop eax
 
; Clear the socket variables
;xxx stdcall net_socket_free, [sockAddr]
stdcall net_socket_free, ebx
 
.exit:
destroyTCB:
pop eax
; Clear the socket varaibles
xor eax, eax
ret
mov edi, ebx
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
 
.error:
DEBUGF 1, "K : socket_close_tcp (fail)\n"
or eax, -1
sct_exit:
ret
endp
 
 
 
;***************************************************************************
; Function
; socket_poll
606,20 → 486,12
; returns count in eax.
;
;***************************************************************************
proc socket_poll stdcall
; DEBUGF 1, "socket_poll(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
socket_poll:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.rxDataCount]
 
mov eax, [eax + SOCKET.rxDataCount]
ret
 
.error:
;or eax, -1
xor eax, eax
ret
endp
 
 
;***************************************************************************
631,27 → 503,14
; returns TCB state in eax.
;
;***************************************************************************
proc socket_status stdcall
;; DEBUGF 1, "socket_status(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
socket_status:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.TCBState]
 
mov eax, [eax + SOCKET.TCBState]
ret
 
.error:
;or eax, -1
xor eax, eax
ret
endp
 
; Index2RealAddr ebx
; mov eax, [ebx + SOCKET.TCBState]
;
; ret
 
 
;***************************************************************************
; Function
; socket_read
661,16 → 520,12
; returns # of bytes remaining in eax, data in bl
;
;***************************************************************************
proc socket_read stdcall
; DEBUGF 1, "socket_read(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
mov ebx, eax
socket_read:
Index2RealAddr ebx
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
mov ecx, 1
test eax, eax
jz .error
jz sr2
 
dec eax
mov esi, ebx ; esi is address of socket
682,19 → 537,18
inc esi
 
mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
lea edi, [ebx + SOCKETHEADERSIZE]
lea esi, [edi + 1]
cld
rep movsd
xor ecx, ecx
 
ret
sr1:
jmp sor_exit
 
.error:
;or eax, -1
xor eax, eax
xor ebx, ebx
sr2:
xor bl, bl
 
sor_exit:
ret
endp
 
 
;***************************************************************************
708,27 → 562,22
; returns # of bytes copied in eax
;
;***************************************************************************
proc socket_read_packet stdcall
; DEBUGF 1, "socket_read_packet(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx ; get real socket address
or eax, eax
jz .error
 
mov ebx, eax
socket_read_packet:
Index2RealAddr ebx ; get real socket address
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax ; if count of bytes is zero..
jz .exit ; exit function (eax will be zero)
 
test edx, edx ; if buffer size is zero, copy all data
jz .copy_all_bytes
jz .copyallbytes
cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data
jge .copy_all_bytes
jge .copyallbytes
 
sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy)
mov [ebx + SOCKET.rxDataCount], eax ;
push eax
mov eax, edx ; number of bytes we want to copy must be in eax
call .start_copy ; copy to the application
call .startcopy ; copy to the application
 
mov esi, ebx ; now we're going to copy the remaining bytes to the beginning
add esi, SOCKETHEADERSIZE ; we dont need to copy the header
743,36 → 592,33
and ecx, 3
rep movsb ; copy remaining bytes
 
.exit:
ret ; at last, exit
 
.error:
;or eax, -1
xor eax, eax
ret
 
.copy_all_bytes:
.copyallbytes:
xor esi, esi
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
call .start_copy
ret
 
.start_copy:
mov edi, ecx
mov esi, ebx
.startcopy:
mov edi, ecx ;
; add edi, std_application_base_address ; get data pointer to buffer in application
 
mov esi, ebx ;
add esi, SOCKETHEADERSIZE ; we dont need to copy the header
mov ecx, eax ; eax is count of bytes
push ecx
shr ecx, 2 ; divide eax by 4
cld ; copy all full dwords
rep movsd
rep movsd ;
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
retn ; exit, or go back to shift remaining bytes if any
endp
 
.exit:
ret ; exit, or go back to shift remaining bytes if any
 
 
 
 
;***************************************************************************
; Function
; socket_write
785,22 → 631,19
; could not queue IP packet )
;
;***************************************************************************
proc socket_write stdcall
; DEBUGF 1, "socket_write(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx ; get real socket address
or eax, eax
jz .error
socket_write:
Index2RealAddr ebx
 
mov ebx, eax
 
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx + SOCKET.Status], SOCK_EMPTY
je .error
cmp [ebx], dword SOCK_EMPTY
je sw_exit
 
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
je sw_exit
 
; Save the queue entry number
push eax
819,46 → 662,55
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header (some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_PACKET.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_PACKET.DestinationAddress], eax
mov eax, [ebx + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
 
mov [edx + IP_PACKET.VersionAndIHL], 0x45
mov [edx + IP_PACKET.TypeOfService], 0
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
 
pop eax ; Get the UDP data length
push eax
 
add eax, 20 + 8 ; add IP header and UDP header lengths
xchg al, ah
mov [edx + IP_PACKET.TotalLength], ax
xor eax, eax
mov [edx + IP_PACKET.Identification], ax
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_PACKET.TimeToLive], 0x20
mov [edx + IP_PACKET.Protocol], PROTOCOL_UDP
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 17
mov [edx + 9], al
 
; Checksum left unfilled
mov [edx + IP_PACKET.HeaderChecksum], ax
xor ax, ax
mov [edx + 10], ax
 
; Fill in the UDP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
mov [edx + 20 + UDP_PACKET.SourcePort], ax
mov ax, [ebx + 12]
mov [edx + 20], ax
 
mov ax, [ebx + SOCKET.RemotePort]
mov [edx + 20 + UDP_PACKET.DestinationPort], ax
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax
 
pop eax
push eax
 
add eax, 8
xchg al, ah
mov [edx + 20 + UDP_PACKET.Length], ax
mov [edx + 20 + 4], ah
mov [edx + 20 + 5], al
 
; Checksum left unfilled
xor eax, eax
mov [edx + 20 + UDP_PACKET.Checksum], ax
xor ax, ax
mov [edx + 20 + 6], ax
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
878,15 → 730,16
; we have edx as IPbuffer ptr.
; Fill in the UDP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_PACKET.SourceAddress]
mov eax, [edx + 12]
mov [pseudoHeader], eax
mov eax, [edx + IP_PACKET.DestinationAddress]
mov eax, [edx + 16]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_UDP shl 8 + 0 ; 0 + protocol
mov ax, 0x1100 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 8
mov eax, ebx
xchg al, ah
mov [pseudoHeader + 10], ax
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
 
mov eax, pseudoHeader
mov [checkAdd1], eax
904,43 → 757,44
 
; If the UDP checksum computes to 0, we must make it 0xffff
; (0 is reserved for 'not used')
test ax, ax
jnz @f
cmp ax, 0
jne sw_001
mov ax, 0xffff
 
@@: xchg al, ah
mov [edx + 20 + UDP_PACKET.Checksum], ax
sw_001:
mov [edx + 20 + 6], ah
mov [edx + 20 + 7], al
 
; Fill in the IP header checksum
GET_IHL ecx,edx ; get IP-Header length
stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size
xchg al, ah
mov [edx + IP_PACKET.HeaderChecksum], ax
 
mov [edx + 10], ah
mov [edx + 11], al
 
; Check destination IP address.
; If it is the local host IP, route it back to IP_RX
 
pop ebx
mov eax, NET1OUT_QUEUE
mov ecx, [edx + SOCKET.RemoteIP]
 
mov ecx, [ edx + 16]
mov edx, [stack_ip]
cmp edx, ecx
jne .not_local
jne sw_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
sw_notlocal:
; Send it.
call queue
 
xor eax, eax
ret
 
.error:
or eax, -1
sw_exit:
ret
endp
 
 
 
;***************************************************************************
; Function
; socket_write_tcp
953,33 → 807,30
; could not queue IP packet )
;
;***************************************************************************
proc socket_write_tcp stdcall
local sockAddr dd ?
socket_write_tcp:
Index2RealAddr ebx
 
; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
mov [sktAddr], ebx
 
mov ebx, eax
mov [sockAddr], ebx
 
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx + SOCKET.Status], SOCK_EMPTY
je .error
cmp [ebx], dword SOCK_EMPTY
je swt_exit
 
; If the sockets window timer is nonzero, do not queue packet
; TODO - done
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .error
cmp [ebx + SOCKET.wndsizeTimer], dword 0
jne swt_exit
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
je swt_exit
 
push eax
 
mov bl, 0x10 ; ACK
 
; Get the address of the callers data
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
990,8 → 841,7
push eax
 
push ecx
mov bl, TH_ACK
stdcall build_tcp_packet, [sockAddr]
call buildTCPPacket
pop ecx
 
; Check destination IP address.
1002,12 → 852,13
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov ecx, [sktAddr ]
mov ecx, [ecx + 16]
cmp edx, ecx
jne swt_notlocal
mov eax, IPIN_QUEUE
 
.not_local:
swt_notlocal:
pop ecx
 
push ebx ; save ipbuffer number
1014,11 → 865,11
 
call queue
 
mov esi, [sockAddr]
mov esi, [sktAddr]
 
; increament SND.NXT in socket
; Amount to increment by is in ecx
add esi, SOCKET.SND_NXT
add esi, 48
call add_inet_esi
 
pop ebx
1028,17 → 879,17
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
swt003:
cmp ecx, NUMRESENDENTRIES
je .exit ; None found
;cmp byte[esi], 0xff ; XTODO: 0xff -> 0
cmp dword[esi + 4], 0
je @f ; found one
je swt001 ; None found
cmp [esi], byte 0xFF
je swt002 ; found one
inc ecx
add esi, 8
jmp .next_resendq
add esi, 4
jmp swt003
 
@@: push ebx
swt002:
push ebx
 
; OK, we have a buffer descriptor ptr in esi.
; resend entry # in ecx
1048,19 → 899,20
; retry time
; fill IP buffer associated with this descriptor
 
stdcall net_socket_addr_to_num, [sockAddr]
;mov [esi], al ; XTODO: al -> eax
mov [esi + 4], eax
mov byte[esi + 1], TCP_RETRIES
mov word[esi + 2], TCP_TIMEOUT
mov eax, [sktAddr]
sub eax, sockets
shr eax, 12 ; get skt #
mov [esi], al
mov [esi + 1], byte TCP_RETRIES
mov [esi + 2], word TCP_TIMEOUT
 
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
swt002a:
add edi, IPBUFFSIZE
loop swt002a
 
@@: add edi, IPBUFFSIZE
loop @b
 
; we have dest buffer location in edi
pop eax
; convert source buffer pointer eax to the absolute address
1074,11 → 926,9
cld
rep movsb
 
.exit:
swt001:
xor eax, eax
 
swt_exit:
ret
 
.error:
or eax, -1
ret
endp
/kernel/branches/kolibri_pe/network/ip.inc
87,10 → 87,6
}
 
 
include "tcp.inc"
include "udp.inc"
include "icmp.inc"
 
;***************************************************************************
; Function
; ip_rx
118,13 → 114,11
 
mov ebx, eax ; ebx=pointer to IP_PACKET
 
; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1
 
; Validate the IP checksum
mov dx, word[ebx + IP_PACKET.HeaderChecksum]
xchg dh,dl ; Get the checksum in intel format
mov [ebx + IP_PACKET.HeaderChecksum], 0 ; clear checksum field - need to when
mov [ebx + IP_PACKET.HeaderChecksum], word 0 ; clear checksum field - need to when
; recalculating checksum
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
133,13 → 127,9
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size
cmp dx, ax
 
; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax
 
jnz .dump.1 ;if CHECKSUM isn't valid then dump packet
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!!
jnz .dump ;if CHECKSUM isn't valid then dump packet
 
; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip]
 
; Validate the IP address, if it isn't broadcast
mov eax, [stack_ip]
cmp dword[ebx + IP_PACKET.DestinationAddress], eax
147,37 → 137,22
 
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
cmp dword[ebx + IP_PACKET.DestinationAddress], 0xffffffff
jne .dump
 
mov eax, [ebx + IP_PACKET.DestinationAddress]
cmp eax, 0xffffffff
;je @f
;mov ecx, [stack_ip]
;and eax, [subnet_mask]
;and ecx, [subnet_mask]
;cmp eax, ecx
;jne .dump.2
;mov eax, [ebx + IP_PACKET.DestinationAddress]
;or eax, [subnet_mask]
;cmp eax, 0xffffffff
jne .dump.2
 
@@:
mov al, [ebx + IP_PACKET.VersionAndIHL]
and al, 0x0f ;get IHL(header length)
cmp al, 0x05 ;if IHL!= 5*4(20 bytes)
; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al
jnz .dump.3 ;then dump it
jnz .dump ;then dump it
 
; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2
cmp byte[ebx + IP_PACKET.TimeToLive], byte 0
je .dump ;if TTL==0 then dump it
 
cmp [ebx + IP_PACKET.TimeToLive], 0
je .dump.4 ;if TTL==0 then dump it
 
mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset]
mov ax, word[ebx + IP_PACKET.FlagsAndFragmentOffset]
and ax, 0xFFBF ;get flags
; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax
cmp ax, 0 ;if some flags was set then we dump this packet
jnz .dump.5 ;the flags should be used for fragmented packets
jnz .dump ;the flags should be used for fragmented packets
 
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
186,7 → 161,7
 
cmp al , PROTOCOL_TCP
jne .not_tcp
; DEBUGF 1,"K : ip_rx - TCP packet\n"
DEBUGF 1,"K : ip_rx - TCP packet\n"
mov eax, dword[buffer_number]
call tcp_rx
jmp .exit
194,7 → 169,7
.not_tcp:
cmp al, PROTOCOL_UDP
jne .not_udp
; DEBUGF 1,"K : ip_rx - UDP packet\n"
DEBUGF 1,"K : ip_rx - UDP packet\n"
mov eax, dword[buffer_number]
call udp_rx
jmp .exit
201,9 → 176,9
 
.not_udp:
cmp al, PROTOCOL_ICMP
jne .dump.6 ;protocol ain't supported
jne .dump ;protocol ain't supported
 
; DEBUGF 1,"K : ip_rx - ICMP packet\n"
DEBUGF 1,"K : ip_rx - ICMP packet\n"
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
mov eax, dword[buffer_number]
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength
210,32 → 185,13
jmp .exit
 
 
.dump.1:
DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax
jmp .dump.x
.dump:
; No protocol handler available, so
; silently dump the packet, freeing up the queue buffer
 
.dump.2:
DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1
jmp .dump.x
inc dword [dumped_rx_count]
 
.dump.3:
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al
jmp .dump.x
 
.dump.4:
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", [ebx + IP_PACKET.TimeToLive]
jmp .dump.x
 
.dump.5:
DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax
jmp .dump.x
 
.dump.6:
DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1
 
.dump.x:
inc dword[dumped_rx_count]
mov eax, [buffer_number]
mov eax, dword[buffer_number]
call freeBuff
 
.exit:
/kernel/branches/kolibri_pe/network/queue.inc
43,19 → 43,18
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
uglobal
freeBuff_cnt dd ?
endg
freeBuff:
; inc [freeBuff_cnt]
; DEBUGF 1, "K : freeBuff (%u)\n", [freeBuff_cnt]
push ebx
push ecx
mov ebx, queues + EMPTY_QUEUE * 2
mov ebx, EMPTY_QUEUE
shl ebx, 1
add ebx, queues
cli ; Ensure that another process does not interfer
mov cx, [ebx]
movzx ecx, word [ebx]
mov [ebx], ax
mov [queueList + eax * 2], cx
shl eax, 1
add eax, queueList
mov [eax], cx
sti
pop ecx
pop ebx
106,12 → 105,7
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
uglobal
queue_cnt dd ?
endg
queue:
; inc [queue_cnt]
; DEBUGF 1, "K : queue (%u)\n", [queue_cnt]
push ebx
shl ebx, 1
add ebx, queueList ; eax now holds address of queue entry
161,9 → 155,6
; all other registers preserved
;
;***************************************************************************
uglobal
dequeue_cnt dd ?
endg
dequeue:
push ebx
shl eax, 1
173,8 → 164,6
movzx eax, word [eax]
cmp ax, NO_BUFFER
je dq_exit
; inc [dequeue_cnt]
; DEBUGF 1, "K : dequeue (%u)\n", [dequeue_cnt]
push eax
shl eax, 1
add eax, queueList ; eax now holds address of queue entry
/kernel/branches/kolibri_pe/network/stack.inc
37,7 → 37,7
 
uglobal
StackCounters:
dumped_rx_count dd 0
dumped_rx_count: dd 0
arp_tx_count: dd 0
arp_rx_count: dd 0
ip_rx_count: dd 0
46,9 → 46,9
 
; socket buffers
SOCKETBUFFSIZE equ 4096 ; state + config + buffer.
SOCKETHEADERSIZE equ 76+8+8 ; thus 4096 - SOCKETHEADERSIZE bytes data
SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data
 
;NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20
NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20
 
; IPBUFF status values
BUFF_EMPTY equ 0
94,7 → 94,7
; TODO :: empty memory area
 
; Address of selected socket
;sktAddr equ stack_data + 32
sktAddr equ stack_data + 32
; Parameter to checksum routine - data ptr
checkAdd1 equ stack_data + 36
; Parameter to checksum routine - 2nd data ptr
110,8 → 110,8
pseudoHeader equ stack_data + 50
 
; receive and transmit IP buffer allocation
;sockets equ stack_data + 62
Next_free2 equ stack_data + 62;Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
sockets equ stack_data + 62
Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
; 1560 byte buffer for rx / tx ethernet packets
Ether_buffer equ Next_free2
Next_free3 equ Ether_buffer + 1518
128,14 → 128,9
 
 
;resendQ equ 0x770000
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP ; XTODO: validate size
resendBuffer equ resendQ + ( 8 * NUMRESENDENTRIES ) ; for TCP
resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP
 
 
uglobal
net_sockets rd 2
endg
 
; simple macro for memory set operation
macro _memset_dw adr,value,amount
{
156,6 → 151,9
include "queue.inc"
include "eth_drv/ethernet.inc"
include "ip.inc"
include "icmp.inc"
include "tcp.inc"
include "udp.inc"
include "socket.inc"
 
;***************************************************************************
173,11 → 171,8
stack_init:
; Init two address spaces with default values
_memset_dw stack_data_start, 0, 0x20000/4
_memset_dw resendQ, 0, NUMRESENDENTRIES * 2
_memset_dw resendQ, 0xFFFFFFFF, NUMRESENDENTRIES
 
mov [net_sockets], 0
mov [net_sockets + 4], 0
 
; Queries initialization
call queueInit
 
/kernel/branches/kolibri_pe/network/udp.inc
71,8 → 71,7
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
 
proc udp_rx stdcall
udp_rx:
push eax
 
; First validate the header & checksum. Discard buffer if error
81,53 → 80,69
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
 
mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from
movzx ebx, word [edx + 22] ; get the local port from
; the IP packet's UDP header
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
mov ebx, net_sockets
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .exit ; No match, so exit
cmp [ebx + SOCKET.LocalPort], ax ; ax will hold the 'wrong' value,
fs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value,
; but the comparision is correct
jne .next_socket ; Return back if no match
loopnz fs1 ; Return back if no match
jz fs_done
 
; No match, so exit
jmp udprx_001
 
fs_done:
; For dhcp, we must allow any remote server to respond.
; I will accept the first incoming response to be the one
; I bind to, if the socket is opened with a destination IP address of
; 255.255.255.255
cmp [ebx + SOCKET.RemoteIP], 0xffffffff
je @f
mov ebx, [eax + sockets + 16]
cmp ebx, 0xffffffff
je udprx_002
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet
cmp [ebx + SOCKET.RemoteIP], ebx
jne .exit ; Quit if the source IP is not valid
mov ebx, [edx + 12] ; get the Source address from the IP packet
cmp [eax + sockets + 16], ebx
jne udprx_001 ; Quit if the source IP is not valid
 
@@: ; OK - we have a valid UDP packet for this socket.
udprx_002:
; OK - we have a valid UDP packet for this socket.
; First, update the sockets remote port number with the incoming msg
; - it will have changed
; from the original ( 69 normally ) to allow further connects
mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port
movzx ebx, word [edx + 20] ; get the UDP source port
; ( was 69, now new )
mov [ebx + SOCKET.RemotePort], ax
mov [eax + sockets + 20], bx
 
; Now, copy data to socket. We have socket address as [eax + sockets].
; We have IP packet in edx
 
; get # of bytes in ecx
movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract
xchg cl, ch ; 20 + 8 gives data length
movzx ecx, byte [edx + 3] ; total length of IP packet. Subtract
mov ch, byte [edx + 2] ; 20 + 8 gives data length
sub ecx, 28
 
mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer
add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer
mov ebx, eax
add ebx, sockets ; ebx = address of actual socket
 
; ecx has count, edx points to data
mov eax, [ebx+ 4] ; get socket owner PID
push eax
 
mov eax, [ebx + 24] ; get # of bytes already in buffer
add [ebx + 24], ecx ; increment the count of bytes in buffer
 
; point to the location to store the data
add ebx, eax
add ebx, SOCKETHEADERSIZE
 
; ebx = location for first byte, ecx has count,
; edx points to data
 
add edx, 28 ; edx now points to the data
lea edi, [ebx + eax + SOCKETHEADERSIZE]
mov edi, ebx
mov esi, edx
 
cld
134,28 → 149,25
rep movsb ; copy the data across
 
; flag an event to the application
mov eax, [ebx + SOCKET.PID] ; get socket owner PID
pop eax
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
newsearch:
cmp [esi], eax
je .found_pid
je foundPID
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
jbe newsearch
 
jmp .exit
 
.found_pid:
foundPID:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event
 
mov [check_idle_semaphore], 200
 
.exit:
udprx_001:
pop eax
call freeBuff ; Discard the packet
ret
endp
/kernel/branches/kolibri_pe/docs/sysfuncr.txt
3402,9 → 3402,9
* ebx = 㪠§ â¥«ì ­  ¨§®¡à ¦¥­¨¥
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
* esi = ç¨á«® ¡¨â ­  ¯¨ªá¥«ì, ¤®«¦­® ¡ëâì 1, 4, 8, 15, 16, 24 ¨«¨ 32
* edi = 㪠§ â¥«ì ­  ¯ «¨âàã (2 ¢ á⥯¥­¨ esi 梥⮢ 0x00RRGGBB);
¨£­®à¨àã¥âáï ¯à¨ esi > 8
* esi = ç¨á«® ¡¨â ­  ¯¨ªá¥«ì, ¤®«¦­® ¡ëâì 8, 16, 24 ¨«¨ 32
* edi = 㪠§ â¥«ì ­  ¯ «¨âàã (256 梥⮢ 0x00RRGGBB);
¨£­®à¨àã¥âáï ¯à¨ esi = 16, 24 ¨ 32
* ebp = ᬥ饭¨¥ ¤ ­­ëå ª ¦¤®© á«¥¤ãî饩 áâப¨ ¨§®¡à ¦¥­¨ï
®â­®á¨â¥«ì­® ¯à¥¤ë¤ã饩
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
3413,23 → 3413,13
* Š®®à¤¨­ âë ¨§®¡à ¦¥­¨ï - íâ® ª®®à¤¨­ âë ¢¥àå­¥£® «¥¢®£® 㣫 
¨§®¡à ¦¥­¨ï ®â­®á¨â¥«ì­® ®ª­ .
*  §¬¥à ¨§®¡à ¦¥­¨ï ¢ ¡ ©â å ¥áâì xsize*ysize.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 1 ¡¨â®¬ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï,
§  ¨áª«î祭¨¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤­¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â
¨­ä®à¬ æ¨î ® 梥⥠8 ¯¨ªá¥«¥©, áâ à訩 ¡¨â ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã
¯¨ªá¥«î.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 4 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï,
§  ¨áª«î祭¨¥¬ ¯®á«¥¤­¨å ¡ ©â®¢ áâப (¥á«¨ è¨à¨­  ¨§®¡à ¦¥­¨ï
­¥çñâ­ ), ᮤ¥à¦¨â ¨­ä®à¬ æ¨î ® 梥⥠2 ¯¨ªá¥«¥©, áâ àè ï â¥âà ¤ 
ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã ¯¨ªá¥«î.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 8 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï
à áᬠâਢ ¥âáï ª ª ¨­¤¥ªá ¢ ¯ «¨âà¥.
* …᫨ ¨§®¡à ¦¥­¨¥ ¨á¯®«ì§ã¥â ­¥ ¢á¥ 256 梥⮢,   ¬¥­ìè¥,
à §¬¥à ¯ «¨âàë ¬®¦¥â ¡ëâì ¬¥­ìè¥ 256.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 15 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 16 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï ª ª (¢ ¡¨â®¢®¬ ¯à¥¤áâ ¢«¥­¨¨) 0RRRRRGGGGGBBBBB -
¯® 5 ¯¨ªá¥«¥© ­  ª ¦¤ë© 梥â.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 16 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï ª ª RRRRRGGGGGGBBBBB (á奬  5+6+5).
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 24 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï âà¥¬ï ¡ ©â ¬¨ - ¯®á«¥¤®¢ â¥«ì­® ᨭïï, §¥«ñ­ ï,
ªà á­ ï á®áâ ¢«ïî騥 梥â .