/kernel/branches/Kolibri-acpi/network/ARP.inc |
---|
58,13 → 58,13 |
align 4 |
uglobal |
NumARP dd ? |
ARP_table rb ARP_TABLE_SIZE * sizeof.ARP_entry ; TODO: separate ARP table and stats per interface |
ARP_table rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry) |
ARP_PACKETS_TX rd MAX_NET_DEVICES |
ARP_PACKETS_RX rd MAX_NET_DEVICES |
ARP_CONFLICTS rd MAX_NET_DEVICES |
ARP_entries_num rd NET_DEVICES_MAX |
ARP_PACKETS_TX rd NET_DEVICES_MAX |
ARP_PACKETS_RX rd NET_DEVICES_MAX |
ARP_CONFLICTS rd NET_DEVICES_MAX |
endg |
81,10 → 81,8 |
macro ARP_init { |
xor eax, eax |
mov [NumARP], eax |
mov edi, ARP_PACKETS_TX |
mov ecx, 3*MAX_NET_DEVICES |
mov edi, ARP_entries_num |
mov ecx, 4*NET_DEVICES_MAX |
rep stosd |
} |
111,11 → 109,15 |
; The last status value is provided to allow the network layer to delete |
; a packet that is queued awaiting an ARP response |
mov ecx, [NumARP] |
xor edi, edi |
.loop_outer: |
mov ecx, [ARP_entries_num + 4*edi] |
test ecx, ecx |
jz .exit |
mov esi, ARP_table |
mov esi, (ARP_TABLE_SIZE * sizeof.ARP_entry) |
imul esi, edi |
add esi, ARP_table |
.loop: |
cmp [esi + ARP_entry.TTL], ARP_STATIC_ENTRY |
je .next |
133,9 → 135,9 |
cmp [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE |
je .response_timeout |
push esi ecx |
push esi edi ecx |
call ARP_del_entry |
pop ecx esi |
pop ecx edi esi |
jmp .next |
146,6 → 148,9 |
jmp .next |
.exit: |
inc edi |
cmp edi, NET_DEVICES_MAX |
jb .loop_outer |
} |
196,11 → 201,13 |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n" |
mov ecx, [NumARP] |
mov ecx, [ARP_entries_num + 4*edi] |
test ecx, ecx |
jz .exit |
mov esi, ARP_table |
mov esi, (ARP_TABLE_SIZE * sizeof.ARP_entry) |
imul esi, edi |
add esi, ARP_table |
.loop: |
cmp [esi + ARP_entry.IP], eax |
je .gotit |
298,32 → 305,27 |
; |
; ARP_output_request |
; |
; IN: ip in eax |
; device in edi |
; IN: ebx = device ptr |
; eax = IP |
; OUT: / |
; scratched: probably everything |
; |
;--------------------------------------------------------------------------- |
align 4 |
ARP_output_request: |
push eax ; DestIP |
pushd [IP_LIST + edi] ; SenderIP |
inc [ARP_PACKETS_TX + edi] ; assume we will succeed |
push eax |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u\n",\ |
[esp + 4]:1, [esp + 5]:1, [esp + 6]:1, [esp + 7]:1 |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\ |
[esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx |
mov ebx, [NET_DRV_LIST + edi] ; device ptr |
lea eax, [ebx + ETH_DEVICE.mac] ; local device mac |
mov edx, ETH_BROADCAST ; broadcast mac |
mov ecx, sizeof.ARP_header |
mov di, ETHER_ARP |
mov di, ETHER_PROTO_ARP |
call ETH_output |
jz .exit |
mov ecx, eax |
mov [edi + ARP_header.HardwareType], 0x0100 ; Ethernet |
mov [edi + ARP_header.ProtocolType], 0x0008 ; IP |
mov [edi + ARP_header.HardwareSize], 6 ; MAC-addr length |
331,29 → 333,29 |
mov [edi + ARP_header.Opcode], ARP_REQ_OPCODE ; Request |
add edi, ARP_header.SenderMAC |
lea esi, [ebx + ETH_DEVICE.mac] ; SenderMac |
movsw ; |
movsd ; |
pop eax ; SenderIP |
stosd ; |
mov eax, -1 ; DestMac |
stosd ; |
stosw ; |
pop eax ; DestIP |
stosd ; |
; mov esi, [ebx + NET_DEVICE.number] |
xor esi, esi ;;;; FIXME |
inc esi ;;;;;;;;; |
inc [ARP_PACKETS_TX + 4*esi] ; assume we will succeed |
lea esi, [IP_LIST + 4*esi] ; SenderIP |
movsd |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: device=%x\n", ebx |
mov esi, ETH_BROADCAST ; DestMac |
movsw ; |
movsd ; |
popd [edi] ; DestIP |
push edx ecx |
push edx eax |
call [ebx + NET_DEVICE.transmit] |
ret |
.exit: |
add esp, 4 + 4 |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_output_request: failed\n" |
sub eax, eax |
add esp, 4 |
DEBUGF DEBUG_NETWORK_ERROR, "ARP_output_request: send failed\n" |
ret |
362,50 → 364,64 |
; ARP_add_entry (or update) |
; |
; IN: esi = ptr to entry (can easily be made on the stack) |
; edi = device num |
; OUT: eax = entry #, -1 on error |
; edi = ptr to newly created entry |
; esi = ptr to newly created entry |
; |
;----------------------------------------------------------------- ; TODO: use a mutex |
align 4 |
ARP_add_entry: |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: " |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi |
mov ecx, [NumARP] |
mov ecx, [ARP_entries_num + 4*edi] |
cmp ecx, ARP_TABLE_SIZE ; list full ? |
jae .error |
jae .full |
xor eax, eax |
mov edi, ARP_table |
mov ecx, [esi + ARP_entry.IP] |
; From this point on, we can only fail if IP has a static entry, or if table is corrupt. |
inc [ARP_entries_num + 4*edi] ; assume we will succeed |
push edi |
xor ecx, ecx |
imul edi, ARP_TABLE_SIZE*sizeof.ARP_entry |
add edi, ARP_table |
mov eax, [esi + ARP_entry.IP] |
.loop: |
cmp [edi + ARP_entry.Status], ARP_NO_ENTRY ; is this slot empty? |
je .add |
cmp [edi + ARP_entry.IP], ecx ; if not, check if it doesnt collide |
cmp [edi + ARP_entry.IP], eax ; if not, check if it doesnt collide |
jne .maybe_next |
cmp [edi + ARP_entry.TTL], ARP_STATIC_ENTRY ; ok, its the same IP, update it if not static |
jne .add |
DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry: failed, IP already has a static entry\n" |
jmp .error |
.maybe_next: ; try the next slot |
add edi, sizeof.ARP_entry |
inc eax |
cmp eax, ARP_TABLE_SIZE |
jae .error |
jmp .loop |
inc ecx |
cmp ecx, ARP_TABLE_SIZE |
jb .loop |
.add: |
push ecx |
mov ecx, sizeof.ARP_entry/2 |
rep movsw |
inc [NumARP] |
sub edi, sizeof.ARP_entry |
DEBUGF DEBUG_NETWORK_VERBOSE, "entry=%u\n", eax |
pop ecx |
lea esi, [edi - sizeof.ARP_entry] |
pop edi |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_add_entry: entry=%u\n", ecx |
ret |
.error: |
DEBUGF DEBUG_NETWORK_VERBOSE, "failed\n" |
pop edi |
dec [ARP_entries_num + 4*edi] |
DEBUGF DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n" |
.full: |
mov eax, -1 |
ret |
415,6 → 431,7 |
; ARP_del_entry |
; |
; IN: esi = ptr to arp entry |
; edi = device number |
; OUT: / |
; |
;----------------------------------------------------------------- |
421,23 → 438,28 |
align 4 |
ARP_del_entry: |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: entry=%x entrys=%u\n", esi, [NumARP] |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: entry=%x entrys=%u\n", esi, [ARP_entries_num + 4*edi] |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: IP=%u.%u.%u.%u\n", \ |
[esi + ARP_entry.IP]:1, [esi + ARP_entry.IP + 1]:1, [esi + ARP_entry.IP + 2]:1, [esi + ARP_entry.IP + 3]:1 |
mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry |
push edi |
imul edi, (ARP_TABLE_SIZE) * sizeof.ARP_entry |
lea ecx, [ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry + edi] |
sub ecx, esi |
shr ecx, 1 |
; move all trailing entries, sizeof.ARP_entry bytes to left. |
mov edi, esi |
add esi, sizeof.ARP_entry |
rep movsw |
; now add an empty entry to the end (erasing previous one) |
xor eax, eax |
mov ecx, sizeof.ARP_entry/2 |
rep stosw |
dec [NumARP] |
pop edi |
dec [ARP_entries_num + 4*edi] |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_del_entry: success\n" |
ret |
465,7 → 487,7 |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah |
rol eax, 16 |
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u\n", al, ah |
DEBUGF DEBUG_NETWORK_VERBOSE, ".%u.%u device: %u\n", al, ah, edi |
rol eax, 16 |
cmp eax, 0xffffffff |
474,25 → 496,24 |
;-------------------------------- |
; Try to find the IP in ARP_table |
mov ecx, [NumARP] |
mov ecx, [ARP_entries_num + 4*edi] |
test ecx, ecx |
jz .not_in_list |
mov esi, ARP_table + ARP_entry.IP |
mov esi, edi |
imul esi, sizeof.ARP_entry * ARP_TABLE_SIZE |
add esi, ARP_table + ARP_entry.IP |
.scan_loop: |
cmp [esi], eax |
je .found_it |
add esi, sizeof.ARP_entry |
loop .scan_loop |
dec ecx |
jnz .scan_loop |
.not_in_list: |
DEBUGF DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n" |
;-------------------- |
; Send an ARP request |
push eax edi ; save IP for ARP_output_request |
; Now create the ARP entry |
; Now craft the ARP entry on the stack |
pushw ARP_REQUEST_TTL ; TTL |
pushw ARP_AWAITING_RESPONSE ; status |
pushd 0 ; mac |
499,21 → 520,27 |
pushw 0 |
pushd eax ; ip |
mov esi, esp |
; Add it to the list |
call ARP_add_entry |
; Delete the temporary entry |
add esp, sizeof.ARP_entry ; clear the entry from stack |
; If we could not add it to the list, give up |
cmp eax, -1 ; did ARP_add_entry fail? |
je .full |
mov esi, edi |
pop edi eax ; IP in eax, device number in edi, for ARP_output_request |
;----------------------------------------------- |
; At this point, we got an ARP entry in the list |
; Now send a request packet on the network |
pop edi eax ; IP in eax, device number in ebx, for ARP_output_request |
push esi edi |
call ARP_output_request ; And send a request |
mov ebx, [NET_DRV_LIST + 4*edi] |
call ARP_output_request |
pop edi esi |
;----------------------------------------------- |
; At this point, we got an ARP entry in the list |
.found_it: |
cmp [esi + ARP_entry.Status], ARP_VALID_MAPPING ; Does it have a MAC assigned? |
je .valid |
558,7 → 585,7 |
; |
; ARP_API |
; |
; This function is called by system function 75 |
; This function is called by system function 76 |
; |
; IN: subfunction number in bl |
; device number in bh |
606,17 → 633,19 |
ret |
.entries: |
mov eax, [NumARP] |
mov eax, [ARP_entries_num + eax] |
ret |
.read: |
cmp ecx, [NumARP] |
cmp ecx, [ARP_entries_num + eax] |
jae .error |
shr eax, 2 |
imul eax, sizeof.ARP_entry*ARP_TABLE_SIZE |
add eax, ARP_table |
; edi = pointer to buffer |
; ecx = # entry |
imul ecx, sizeof.ARP_entry |
add ecx, ARP_table |
mov esi, ecx |
lea esi, [eax + ecx] |
mov ecx, sizeof.ARP_entry/2 |
rep movsw |
625,20 → 654,24 |
.write: |
; esi = pointer to buffer |
mov edi, eax |
shr edi, 2 |
call ARP_add_entry ; out: eax = entry number, -1 on error |
ret |
.remove: |
; ecx = # entry |
cmp ecx, [NumARP] |
cmp ecx, [ARP_entries_num + eax] |
jae .error |
imul ecx, sizeof.ARP_entry |
lea esi, [ARP_table + ecx] |
mov edi, eax |
shr edi, 2 |
call ARP_del_entry |
ret |
.send_announce: |
mov edi, eax |
mov ebx, [NET_DRV_LIST + eax] |
mov eax, [IP_LIST + eax] |
call ARP_output_request ; now send a gratuitous ARP |
ret |
/kernel/branches/Kolibri-acpi/network/IPv4.inc |
---|
58,15 → 58,15 |
align 4 |
uglobal |
IP_LIST rd MAX_NET_DEVICES |
SUBNET_LIST rd MAX_NET_DEVICES |
DNS_LIST rd MAX_NET_DEVICES |
GATEWAY_LIST rd MAX_NET_DEVICES |
BROADCAST_LIST rd MAX_NET_DEVICES |
IP_LIST rd NET_DEVICES_MAX |
SUBNET_LIST rd NET_DEVICES_MAX |
DNS_LIST rd NET_DEVICES_MAX |
GATEWAY_LIST rd NET_DEVICES_MAX |
BROADCAST_LIST rd NET_DEVICES_MAX |
IP_packets_tx rd MAX_NET_DEVICES |
IP_packets_rx rd MAX_NET_DEVICES |
IP_packets_dumped rd MAX_NET_DEVICES |
IP_packets_tx rd NET_DEVICES_MAX |
IP_packets_rx rd NET_DEVICES_MAX |
IP_packets_dumped rd NET_DEVICES_MAX |
FRAGMENT_LIST rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot |
endg |
83,7 → 83,7 |
xor eax, eax |
mov edi, IP_LIST |
mov ecx, 7*MAX_NET_DEVICES + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 |
mov ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4 |
rep stosd |
} |
568,7 → 568,7 |
align 4 |
IPv4_output: |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u\n", ecx |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: size=%u ip=0x%x\n", ecx, eax |
cmp ecx, 65500 ; Max IPv4 packet size |
ja .too_large |
575,10 → 575,11 |
push ecx eax edx di |
cmp eax, 1 shl 24 + 127 |
je .loopback |
call IPv4_route ; outputs device number in edi, dest ip in eax |
call IPv4_route ; outputs device number in edi, dest ip in eax |
test edi, edi |
jz .loopback |
call ARP_IP_to_MAC |
test eax, 0xffff0000 ; error bits |
jnz .arp_error |
585,14 → 586,14 |
push ebx ; push the mac onto the stack |
push ax |
inc [IP_packets_tx + edi] ; update stats |
inc [IP_packets_tx + 4*edi] ; update stats |
mov ebx, [NET_DRV_LIST + edi] |
mov ebx, [NET_DRV_LIST + 4*edi] |
lea eax, [ebx + ETH_DEVICE.mac] |
mov edx, esp |
mov ecx, [esp + 10 + 6] |
add ecx, sizeof.IPv4_header |
mov di, ETHER_IPv4 |
mov di, ETHER_PROTO_IPv4 |
call ETH_output |
jz .eth_error |
add esp, 6 ; pop the mac out of the stack |
618,13 → 619,13 |
ret |
.eth_error: |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: ethernet error\n" |
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ethernet error\n" |
add esp, 3*4+2+6 |
xor edi, edi |
ret |
.arp_error: |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_output: ARP error=%x\n", eax |
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax |
add esp, 3*4+2 |
xor edi, edi |
ret |
635,9 → 636,10 |
ret |
.loopback: |
mov dword [esp + 2], eax |
mov dword [esp + 2], eax ; change source IP to dest IP |
mov ecx, [esp + 10] |
add ecx, sizeof.IPv4_header |
mov di, ETHER_IPv4 |
mov edi, AF_INET4 |
call LOOP_output |
jmp .continue |
675,13 → 677,13 |
push ebx ; push the mac |
push ax |
inc [IP_packets_tx + edi] |
mov ebx, [NET_DRV_LIST + edi] |
inc [IP_packets_tx + 4*edi] |
mov ebx, [NET_DRV_LIST + 4*edi] |
lea eax, [ebx + ETH_DEVICE.mac] |
mov edx, esp |
mov ecx, [esp + 6 + 4] |
add ecx, sizeof.IPv4_header |
mov di, ETHER_IPv4 |
mov di, ETHER_PROTO_IPv4 |
call ETH_output |
jz .error |
775,7 → 777,7 |
mov eax, [esp + 3*4] |
lea ebx, [esp + 4*4] |
mov di , ETHER_IPv4 |
mov di , ETHER_PROTO_IPv4 |
call ETH_output |
cmp edi, -1 |
855,7 → 857,7 |
; IPv4_route |
; |
; IN: eax = Destination IP |
; OUT: edi = device id * 4 |
; OUT: edi = device number |
; eax = ip of gateway if nescessary, unchanged otherwise |
; |
;--------------------------------------------------------------------------- |
866,7 → 868,7 |
je .broadcast |
xor edi, edi |
mov ecx, MAX_NET_DEVICES |
mov ecx, NET_DEVICES_MAX |
.loop: |
mov ebx, [IP_LIST+edi] |
and ebx, [SUBNET_LIST+edi] |
875,7 → 877,11 |
and edx, [SUBNET_LIST+edi] |
cmp ebx, edx |
je .found_it |
jne .next |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi |
ret |
.next: |
add edi, 4 |
dec ecx |
882,15 → 888,10 |
jnz .loop |
.invalid: |
xor edi, edi ; if none found, use device 0 as default |
mov eax, [GATEWAY_LIST] |
.found_it: |
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_route: %u\n", edi |
ret |
mov eax, [GATEWAY_LIST+4] ;;; FIXME |
.broadcast: |
xor edi, edi |
xor edi, edi ; if none found, use device 1 as default ;;;; FIXME |
inc di |
ret |
973,7 → 974,8 |
or ebx, ecx |
mov [BROADCAST_LIST + eax], ebx |
mov eax, ecx |
mov ebx, [NET_DRV_LIST + eax] |
mov eax, [IP_LIST + eax] |
call ARP_output_request ; now send a gratuitous ARP |
call NET_send_event |
/kernel/branches/Kolibri-acpi/network/IPv6.inc |
---|
34,13 → 34,13 |
uglobal |
IPv6: |
.addresses rd 4*MAX_NET_DEVICES |
.subnet rd 4*MAX_NET_DEVICES |
.dns rd 4*MAX_NET_DEVICES |
.gateway rd 4*MAX_NET_DEVICES |
.addresses rd 4*NET_DEVICES_MAX |
.subnet rd 4*NET_DEVICES_MAX |
.dns rd 4*NET_DEVICES_MAX |
.gateway rd 4*NET_DEVICES_MAX |
.packets_tx rd MAX_NET_DEVICES |
.packets_rx rd MAX_NET_DEVICES |
.packets_tx rd NET_DEVICES_MAX |
.packets_rx rd NET_DEVICES_MAX |
endg |
/kernel/branches/Kolibri-acpi/network/PPPoE.inc |
---|
113,7 → 113,7 |
; Check that device exists and is ethernet device |
mov ebx, [eax + SOCKET.device] |
cmp ebx, MAX_NET_DEVICES |
cmp ebx, NET_DEVICES_MAX |
ja .bad |
mov ebx, [NET_DRV_LIST + 4*ebx] |
120,7 → 120,7 |
test ebx, ebx |
jz .bad |
cmp [ebx + NET_DEVICE.type], NET_TYPE_ETH |
cmp [ebx + NET_DEVICE.device_type], NET_DEVICE_ETH |
jne .bad |
DEBUGF DEBUG_NETWORK_VERBOSE, "PPPoE_discovery_output: device=%x\n", ebx |
148,9 → 148,9 |
lea esi, [ebx + ETH_DEVICE.mac] |
movsd |
movsw |
cmp word[edi], ETHER_PPP_SESSION ; Allow only PPP_discovery, or LCP |
cmp word[edi], ETHER_PROTO_PPP_SESSION ; Allow only PPP_discovery, or LCP |
je @f |
mov ax, ETHER_PPP_DISCOVERY |
mov ax, ETHER_PROTO_PPP_DISCOVERY |
stosw |
@@: |
200,10 → 200,10 |
mov ax, word [edx + PPPoE_frame.Payload] |
add edx, PPPoE_frame.Payload + 2 |
cmp ax, PPP_IPv4 |
cmp ax, PPP_PROTO_IPv4 |
je IPv4_input |
; cmp ax, PPP_IPv6 |
; cmp ax, PPP_PROTO_IPv6 |
; je IPv6_input |
jmp PPPoE_discovery_input ; Send LCP,CHAP,CBCP,... packets to the PPP dialer |
246,7 → 246,7 |
lea eax, [ebx + ETH_DEVICE.mac] |
lea edx, [PPPoE_MAC] |
add ecx, PPPoE_frame.Payload + 2 |
mov di, ETHER_PPP_SESSION |
mov di, ETHER_PROTO_PPP_SESSION |
call ETH_output |
jz .eth_error |
/kernel/branches/Kolibri-acpi/network/ethernet.inc |
---|
64,19 → 64,19 |
lea edx, [eax + sizeof.ETH_header] |
mov ax, [eax + ETH_header.Type] |
cmp ax, ETHER_IPv4 |
cmp ax, ETHER_PROTO_IPv4 |
je IPv4_input |
cmp ax, ETHER_ARP |
cmp ax, ETHER_PROTO_ARP |
je ARP_input |
cmp ax, ETHER_IPv6 |
cmp ax, ETHER_PROTO_IPv6 |
je IPv6_input |
cmp ax, ETHER_PPP_DISCOVERY |
cmp ax, ETHER_PROTO_PPP_DISCOVERY |
je PPPoE_discovery_input |
cmp ax, ETHER_PPP_SESSION |
cmp ax, ETHER_PROTO_PPP_SESSION |
je PPPoE_session_input |
DEBUGF DEBUG_NETWORK_ERROR, "ETH_input: Unknown packet type=%x\n", ax |
162,7 → 162,7 |
; |
; ETH_API |
; |
; This function is called by system function 75 |
; This function is called by system function 76 |
; |
; IN: subfunction number in bl |
; device number in bh |
174,11 → 174,11 |
align 4 |
ETH_api: |
cmp bh, MAX_NET_DEVICES |
cmp bh, NET_DEVICES_MAX |
ja .error |
movzx eax, bh |
mov eax, dword [NET_DRV_LIST + 4*eax] |
cmp [eax + NET_DEVICE.type], NET_TYPE_ETH |
cmp [eax + NET_DEVICE.device_type], NET_DEVICE_ETH |
jne .error |
and ebx, 0xff |
187,12 → 187,7 |
jmp dword [.table + 4*ebx] |
.table: |
dd .packets_tx ; 0 |
dd .packets_rx ; 1 |
dd .bytes_tx ; 2 |
dd .bytes_rx ; 3 |
dd .read_mac ; 4 |
dd .state ; 5 |
dd .read_mac ; 0 |
.number = ($ - .table) / 4 - 1 |
.error: |
199,28 → 194,7 |
or eax, -1 |
ret |
.packets_tx: |
mov eax, [eax + NET_DEVICE.packets_tx] |
ret |
.packets_rx: |
mov eax, [eax + NET_DEVICE.packets_rx] |
ret |
.bytes_tx: |
mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4] |
mov eax, dword [eax + NET_DEVICE.bytes_tx] |
mov [esp+20+4], ebx ; TODO: fix this ugly code |
ret |
.bytes_rx: |
mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4] |
mov eax, dword [eax + NET_DEVICE.bytes_rx] |
mov [esp+20+4], ebx ; TODO: fix this ugly code |
ret |
.read_mac: |
movzx ebx, word [eax + ETH_DEVICE.mac] |
mov eax, dword [eax + ETH_DEVICE.mac + 2] |
227,7 → 201,4 |
mov [esp+20+4], ebx ; TODO: fix this ugly code |
ret |
.state: |
mov eax, [eax + NET_DEVICE.state] |
ret |
/kernel/branches/Kolibri-acpi/network/icmp.inc |
---|
16,7 → 16,6 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; ICMP types & codes |
100,8 → 99,8 |
align 4 |
uglobal |
ICMP_PACKETS_TX rd MAX_NET_DEVICES |
ICMP_PACKETS_RX rd MAX_NET_DEVICES |
ICMP_PACKETS_TX rd NET_DEVICES_MAX |
ICMP_PACKETS_RX rd NET_DEVICES_MAX |
endg |
116,7 → 115,7 |
xor eax, eax |
mov edi, ICMP_PACKETS_TX |
mov ecx, 2*MAX_NET_DEVICES |
mov ecx, 2*NET_DEVICES_MAX |
rep stosd |
} |
168,9 → 167,6 |
mov esi, [esp] ; Start of buffer |
cmp dword[edi + 4], 1 shl 24 + 127 |
je .loopback |
; Update stats (and validate device ptr) |
call NET_ptr_to_num |
cmp edi,-1 |
178,6 → 174,11 |
inc [ICMP_PACKETS_RX + 4*edi] |
inc [ICMP_PACKETS_TX + 4*edi] |
cmp ebx, LOOPBACK_DEVICE |
je .loopback |
; FIXME: dont assume device is an ethernet device! |
; exchange dest and source address in IP header |
; exchange dest and source MAC in ETH header |
push dword [esi + ETH_header.DstMAC] |
188,10 → 189,10 |
push word [esi + ETH_header.SrcMAC + 4] |
pop word [esi + ETH_header.DstMAC + 4] |
pop word [esi + ETH_header.SrcMAC + 4] |
add esi, sizeof.ETH_header-2 |
add esi, sizeof.ETH_header-4 |
.loopback: |
add esi, 2 |
add esi, 4 |
push [esi + IPv4_header.SourceAddress] |
push [esi + IPv4_header.DestinationAddress] |
pop [esi + IPv4_header.SourceAddress] |
/kernel/branches/Kolibri-acpi/network/loopback.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; loopback.inc ;; |
19,7 → 19,8 |
iglobal |
LOOPBACK_DEVICE: |
.type dd NET_TYPE_LOOPBACK |
.device_type dd NET_DEVICE_LOOPBACK |
.mtu dd 4096 |
.name dd .namestr |
32,6 → 33,9 |
.packets_tx dd 0 |
.packets_rx dd 0 |
.link_state dd -1 |
.hwacc dd 0 |
.namestr db 'loopback', 0 |
.dummy_fn: |
39,6 → 43,23 |
endg |
macro LOOP_init { |
local .fail |
mov ebx, LOOPBACK_DEVICE |
call NET_add_device |
cmp eax, -1 |
je .fail |
mov [IP_LIST], 127 + 1 shl 24 |
mov [SUBNET_LIST], 255 |
mov [BROADCAST_LIST], 0xffffff00 + 127 |
.fail: |
} |
;----------------------------------------------------------------- |
; |
; LOOP_input |
59,12 → 80,16 |
push ecx |
push eax |
inc [LOOPBACK_DEVICE.packets_rx] |
add dword[LOOPBACK_DEVICE.bytes_rx], ecx |
adc dword[LOOPBACK_DEVICE.bytes_rx + 4], 0 |
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: size=%u\n", ecx |
lea edx, [eax + 2] |
mov ax, word[eax] |
lea edx, [eax + 4] |
mov eax, dword[eax] |
mov ebx, LOOPBACK_DEVICE |
cmp ax, ETHER_IPv4 |
cmp eax, AF_INET4 |
je IPv4_input |
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_input: Unknown packet type=%x\n", ax |
81,7 → 106,7 |
; |
; IN: |
; ecx = packet size |
; di = protocol |
; edi = address family |
; |
; OUT: edi = 0 on error, pointer to buffer otherwise |
; eax = buffer start |
96,9 → 121,9 |
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output\n" |
push ecx |
push di |
push edi |
add ecx, 2 |
add ecx, 4 |
cmp ecx, [LOOPBACK_DEVICE.mtu] |
ja .out_of_ram |
stdcall kernel_alloc, ecx |
105,22 → 130,25 |
test eax, eax |
jz .out_of_ram |
mov edi, eax |
pop ax |
stosw |
pop eax |
stosd |
lea eax, [edi - 2] ; Set eax to buffer start |
lea eax, [edi - 4] ; Set eax to buffer start |
pop ecx |
lea edx, [ecx + 2] ; Set edx to complete buffer size |
lea edx, [ecx + 4] ; Set edx to complete buffer size |
mov ebx, LOOPBACK_DEVICE |
.done: |
inc [LOOPBACK_DEVICE.packets_tx] |
add dword[LOOPBACK_DEVICE.bytes_tx], ecx |
adc dword[LOOPBACK_DEVICE.bytes_tx + 4], 0 |
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: ptr=%x size=%u\n", eax, edx |
ret |
.out_of_ram: |
DEBUGF DEBUG_NETWORK_VERBOSE, "LOOP_output: failed\n" |
add esp, 2+4 |
sub edi, edi |
DEBUGF DEBUG_NETWORK_ERROR, "LOOP_output: out of memory\n" |
add esp, 4+4 |
xor edi, edi |
ret |
/kernel/branches/Kolibri-acpi/network/socket.inc |
---|
127,6 → 127,7 |
;------- |
; Timers |
timer_flags dd ? |
timer_retransmission dd ? ; rexmt |
timer_persist dd ? |
timer_keepalive dd ? ; keepalive/syn timeout |
215,9 → 216,9 |
@@: |
pseudo_random eax |
cmp ax, MIN_EPHEMERAL_PORT |
cmp ax, EPHEMERAL_PORT_MIN |
jb @r |
cmp ax, MAX_EPHEMERAL_PORT |
cmp ax, EPHEMERAL_PORT_MAX |
ja @r |
xchg al, ah |
mov [last_UDP_port], ax |
224,9 → 225,9 |
@@: |
pseudo_random eax |
cmp ax, MIN_EPHEMERAL_PORT |
cmp ax, EPHEMERAL_PORT_MIN |
jb @r |
cmp ax, MAX_EPHEMERAL_PORT |
cmp ax, EPHEMERAL_PORT_MAX |
ja @r |
xchg al, ah |
mov [last_TCP_port], ax |
432,11 → 433,10 |
.tcp: |
.udp: |
mov ebx, [edx + 4] ; First, fill in the IP |
cmp ebx, [edx + 4] ; First, fill in the IP |
test ebx, ebx ; If IP is 0, use default |
jnz @f |
mov ebx, [NET_DEFAULT] |
mov ebx, [IP_LIST + 4*ebx] |
mov ebx, [IP_LIST + 4] ;;;;; FIXME !i!i!i |
@@: |
mov [eax + IP_SOCKET.LocalIP], ebx |
483,7 → 483,7 |
.af_inet4: |
cmp [eax + IP_SOCKET.LocalIP], 0 |
jne @f |
push [IP_LIST] ; FIXME |
push [IP_LIST + 4] ; FIXME !i!i!i! |
pop [eax + IP_SOCKET.LocalIP] |
@@: |
632,7 → 632,7 |
cmp [eax + IP_SOCKET.LocalIP], 0 |
jne @f |
push [IP_LIST] |
push [IP_LIST + 4] ;;; fixme!!!! |
pop [eax + IP_SOCKET.LocalIP] |
@@: |
1121,7 → 1121,7 |
je .unbind |
movzx edx, byte [edx + 9] |
cmp edx, MAX_NET_DEVICES |
cmp edx, NET_DEVICES_MAX |
ja s_error |
mov edx, [NET_DRV_LIST + 4*edx] |
/kernel/branches/Kolibri-acpi/network/stack.inc |
---|
31,24 → 31,31 |
DEBUG_NETWORK_ERROR = 1 |
DEBUG_NETWORK_VERBOSE = 0 |
MAX_NET_DEVICES = 16 |
NET_DEVICES_MAX = 16 |
ARP_BLOCK = 1 ; true or false |
MIN_EPHEMERAL_PORT = 49152 |
EPHEMERAL_PORT_MIN = 49152 |
EPHEMERAL_PORT_MAX = 61000 |
MIN_EPHEMERAL_PORT_N = 0x00C0 ; same in Network byte order (FIXME) |
MAX_EPHEMERAL_PORT = 61000 |
MAX_EPHEMERAL_PORT_N = 0x48EE ; same in Network byte order (FIXME) |
; Ethernet protocol numbers |
ETHER_ARP = 0x0608 |
ETHER_IPv4 = 0x0008 |
ETHER_IPv6 = 0xDD86 |
ETHER_PPP_DISCOVERY = 0x6388 |
ETHER_PPP_SESSION = 0x6488 |
ETHER_PROTO_ARP = 0x0608 |
ETHER_PROTO_IPv4 = 0x0008 |
ETHER_PROTO_IPv6 = 0xDD86 |
ETHER_PROTO_PPP_DISCOVERY = 0x6388 |
ETHER_PROTO_PPP_SESSION = 0x6488 |
; Internet protocol numbers |
IP_PROTO_IP = 0 |
IP_PROTO_ICMP = 1 |
IP_PROTO_TCP = 6 |
IP_PROTO_UDP = 17 |
; PPP protocol numbers |
PPP_IPv4 = 0x2100 |
PPP_IPV6 = 0x5780 |
PPP_PROTO_IPv4 = 0x2100 |
PPP_PROTO_IPV6 = 0x5780 |
PPP_PROTO_ETHERNET = 666 ; FIXME |
;Protocol family |
AF_UNSPEC = 0 |
55,17 → 62,8 |
AF_LOCAL = 1 |
AF_INET4 = 2 |
AF_INET6 = 10 |
AF_PPP = 777 |
AF_PPP = 777 ; FIXME |
; Internet protocol numbers |
IP_PROTO_IP = 0 |
IP_PROTO_ICMP = 1 |
IP_PROTO_TCP = 6 |
IP_PROTO_UDP = 17 |
; PPP protocol number |
PPP_PROTO_ETHERNET = 666 |
; Socket types |
SOCK_STREAM = 1 |
SOCK_DGRAM = 2 |
114,12 → 112,6 |
SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8 |
; Network driver types |
NET_TYPE_LOOPBACK = 0 |
NET_TYPE_ETH = 1 |
NET_TYPE_SLIP = 2 |
MAX_backlog = 20 ; maximum backlog for stream sockets |
; Error Codes |
139,11 → 131,23 |
API_PPPOE = 6 |
API_IPv6 = 7 |
; Network device types |
NET_DEVICE_LOOPBACK = 0 |
NET_DEVICE_ETH = 1 |
NET_DEVICE_SLIP = 2 |
; Network link types (link protocols) |
NET_LINK_LOOPBACK = 0 ;;; Really a link type? |
NET_LINK_MAC = 1 ; Media access control (ethernet, isdn, ...) |
NET_LINK_PPP = 2 ; Point to Point Protocol (PPPoE, ...) |
NET_LINK_IEEE802.11 = 3 ; IEEE 802.11 (WiFi) |
; Hardware acceleration bits |
HWACC_TCP_IPv4 = 1 shl 0 |
struct NET_DEVICE |
type dd ? ; Type field |
device_type dd ? ; Type field |
mtu dd ? ; Maximal Transmission Unit |
name dd ? ; Ptr to 0 terminated string |
156,7 → 160,7 |
packets_tx dd ? ; |
packets_rx dd ? ; |
state dd ? ; link state (0 = no link) |
link_state dd ? ; link state (0 = no link) |
hwacc dd ? ; bitmask stating enabled HW accelerations (offload engines) |
ends |
213,8 → 217,7 |
uglobal |
NET_RUNNING dd ? |
NET_DEFAULT dd ? |
NET_DRV_LIST rd MAX_NET_DEVICES |
NET_DRV_LIST rd NET_DEVICES_MAX |
endg |
235,7 → 238,7 |
; Init the network drivers list |
xor eax, eax |
mov edi, NET_RUNNING |
mov ecx, (MAX_NET_DEVICES + 2) |
mov ecx, (NET_DEVICES_MAX + 2) |
rep stosd |
PPPoE_init |
250,6 → 253,8 |
SOCKET_init |
LOOP_init |
mov [net_tmr_count], 0 |
ret |
308,7 → 313,7 |
align 4 |
NET_link_changed: |
DEBUGF DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.state] |
DEBUGF DEBUG_NETWORK_VERBOSE, "NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.link_state] |
align 4 |
NET_send_event: |
345,13 → 350,13 |
DEBUGF DEBUG_NETWORK_VERBOSE, "NET_Add_Device: %x\n", ebx ;;; TODO: use mutex to lock net device list |
cmp [NET_RUNNING], MAX_NET_DEVICES |
cmp [NET_RUNNING], NET_DEVICES_MAX |
jae .error |
;---------------------------------- |
; Check if device is already listed |
mov eax, ebx |
mov ecx, MAX_NET_DEVICES ; We need to check whole list because a device may be removed without re-organizing list |
mov ecx, NET_DEVICES_MAX ; We need to check whole list because a device may be removed without re-organizing list |
mov edi, NET_DRV_LIST |
repne scasd ; See if device is already in the list |
360,7 → 365,7 |
;---------------------------- |
; Find empty slot in the list |
xor eax, eax |
mov ecx, MAX_NET_DEVICES |
mov ecx, NET_DEVICES_MAX |
mov edi, NET_DRV_LIST |
repne scasd |
378,13 → 383,6 |
inc [NET_RUNNING] ; Indicate that one more network device is up and running |
cmp eax, 1 ; If it's the first network device, try to set it as default |
jne @f |
push eax |
call NET_set_default |
pop eax |
@@: |
call NET_send_event |
DEBUGF DEBUG_NETWORK_VERBOSE, "Device number: %u\n", eax |
399,41 → 397,9 |
;----------------------------------------------------------------- |
; |
; NET_set_default |
; |
; API to set the default interface |
; |
; IN: Device num in eax |
; OUT: Device num in eax, -1 on error |
; |
;----------------------------------------------------------------- |
align 4 |
NET_set_default: |
DEBUGF DEBUG_NETWORK_VERBOSE, "NET_set_default: device=%x\n", eax |
cmp eax, MAX_NET_DEVICES |
jae .error |
cmp [NET_DRV_LIST+eax*4], 0 |
je .error |
mov [NET_DEFAULT], eax |
DEBUGF DEBUG_NETWORK_VERBOSE, "NET_set_default: succes\n" |
ret |
.error: |
or eax, -1 |
DEBUGF DEBUG_NETWORK_ERROR, "NET_set_default: failed\n" |
ret |
;----------------------------------------------------------------- |
; |
; NET_Remove_Device: |
; |
; This function is called by etwork drivers, |
; This function is called by network drivers, |
; to unregister network devices from the kernel |
; |
; IN: Pointer to device structure in ebx |
446,28 → 412,12 |
cmp [NET_RUNNING], 0 |
je .error |
cmp [NET_DRV_LIST], ebx |
jne @f |
mov [NET_DRV_LIST], 0 |
cmp [NET_RUNNING], 1 |
je @f |
; there are still active devices, find one and make it default |
xor eax, eax |
mov ecx, MAX_NET_DEVICES |
mov edi, NET_DRV_LIST |
repe scasd |
je @f |
shr edi, 2 |
dec edi |
mov [NET_DEFAULT], edi |
@@: |
;---------------------------- |
; Find the driver in the list |
mov eax, ebx |
mov ecx, MAX_NET_DEVICES |
mov edi, NET_DRV_LIST+4 |
mov ecx, NET_DEVICES_MAX |
mov edi, NET_DRV_LIST |
repne scasd |
jnz .error |
477,10 → 427,11 |
xor eax, eax |
mov dword [edi-4], eax |
dec [NET_RUNNING] |
call NET_send_event |
dec [NET_RUNNING] |
xor eax, eax |
ret |
.error: |
501,7 → 452,7 |
NET_ptr_to_num: |
push ecx |
mov ecx, MAX_NET_DEVICES |
mov ecx, NET_DEVICES_MAX |
mov edi, NET_DRV_LIST |
.loop: |
645,20 → 596,21 |
;---------------------------------------------------------------- |
; |
; System function to work with network devices (75) |
; System function to work with network devices (74) |
; |
;---------------------------------------------------------------- |
align 4 |
sys_network: ; FIXME: make default device easily accessible |
sys_network: |
cmp ebx, -1 |
jne @f |
mov eax, [NET_RUNNING] |
jmp .return |
mov [esp+32], eax |
ret |
@@: |
cmp bh, MAX_NET_DEVICES ; Check if device number exists |
cmp bh, NET_DEVICES_MAX ; Check if device number exists |
jae .doesnt_exist |
mov esi, ebx |
682,17 → 634,20 |
dd .stop ; 3 |
dd .get_ptr ; 4 |
dd .get_drv_name ; 5 |
dd .set_default ; 6 |
dd .packets_tx ; 6 |
dd .packets_rx ; 7 |
dd .bytes_tx ; 8 |
dd .bytes_rx ; 9 |
dd .state ; 10 |
.number = ($ - .table) / 4 - 1 |
.get_type: ; 0 = Get device type (ethernet/token ring/...) |
.get_type: |
mov eax, [eax + NET_DEVICE.device_type] |
mov [esp+32], eax |
ret |
mov eax, [eax + NET_DEVICE.type] |
jmp .return |
.get_dev_name: ; 1 = Get device name |
.get_dev_name: |
mov esi, [eax + NET_DEVICE.name] |
mov edi, ecx |
700,43 → 655,66 |
rep movsd |
xor eax, eax |
jmp .return |
mov [esp+32], eax |
ret |
.reset: ; 2 = Reset the device |
.reset: |
call [eax + NET_DEVICE.reset] |
jmp .return |
mov [esp+32], eax |
ret |
.stop: ; 3 = Stop driver for this device |
.stop: |
call [eax + NET_DEVICE.unload] |
jmp .return |
mov [esp+32], eax |
ret |
.get_ptr: ; 4 = Get driver pointer |
.get_ptr: |
mov [esp+32], eax |
ret |
jmp .return |
.get_drv_name: ; 5 = Get driver name |
.get_drv_name: |
xor eax, eax |
jmp .return |
mov [esp+32], eax |
ret |
.packets_tx: |
mov eax, [eax + NET_DEVICE.packets_tx] |
mov [esp+32], eax |
ret |
.set_default: ; 6 = Set default device |
.packets_rx: |
mov eax, [eax + NET_DEVICE.packets_rx] |
mov [esp+32], eax |
ret |
call NET_set_default |
jmp .return |
.bytes_tx: |
mov ebx, dword [eax + NET_DEVICE.bytes_tx + 4] |
mov [esp+20], ebx |
mov eax, dword [eax + NET_DEVICE.bytes_tx] |
mov [esp+32], eax |
ret |
.doesnt_exist: |
mov eax, -1 |
.bytes_rx: |
mov ebx, dword [eax + NET_DEVICE.bytes_rx + 4] |
mov [esp+20], ebx |
mov eax, dword [eax + NET_DEVICE.bytes_rx] |
mov [esp+32], eax |
ret |
.return: |
.state: |
mov eax, [eax + NET_DEVICE.link_state] |
mov [esp+32], eax |
ret |
.doesnt_exist: |
mov dword[esp+32], -1 |
ret |
;---------------------------------------------------------------- |
; |
; System function to work with protocols (76) |
744,7 → 722,7 |
;---------------------------------------------------------------- |
align 4 |
sys_protocols: |
cmp bh, MAX_NET_DEVICES ; Check if device number exists |
cmp bh, NET_DEVICES_MAX ; Check if device number exists |
jae .doesnt_exist |
mov esi, ebx |
/kernel/branches/Kolibri-acpi/network/tcp.inc |
---|
129,12 → 129,12 |
align 4 |
uglobal |
TCP_segments_tx rd MAX_NET_DEVICES |
TCP_segments_rx rd MAX_NET_DEVICES |
TCP_segments_missed rd MAX_NET_DEVICES |
TCP_segments_dumped rd MAX_NET_DEVICES |
; TCP_bytes_rx rq MAX_NET_DEVICES |
; TCP_bytes_tx rq MAX_NET_DEVICES |
TCP_segments_tx rd NET_DEVICES_MAX |
TCP_segments_rx rd NET_DEVICES_MAX |
TCP_segments_missed rd NET_DEVICES_MAX |
TCP_segments_dumped rd NET_DEVICES_MAX |
; TCP_bytes_rx rq NET_DEVICES_MAX |
; TCP_bytes_tx rq NET_DEVICES_MAX |
TCP_sequence_num dd ? |
TCP_queue rd TCP_QUEUE_SIZE*sizeof.TCP_queue_entry/4 |
TCP_input_event dd ? |
152,7 → 152,7 |
xor eax, eax |
mov edi, TCP_segments_tx |
mov ecx, (6*MAX_NET_DEVICES) |
mov ecx, (6*NET_DEVICES_MAX) |
rep stosd |
pseudo_random eax |
160,8 → 160,7 |
init_queue TCP_queue |
push 1 |
pop ebx |
movi ebx, 1 |
mov ecx, TCP_process_input |
call new_sys_threads |
/kernel/branches/Kolibri-acpi/network/tcp_input.inc |
---|
253,6 → 253,7 |
mov [ebx + TCP_SOCKET.t_idle], 0 |
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_idle |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
;-------------------- |
; Process TCP options |
488,7 → 489,7 |
mov [ebx + TCP_SOCKET.SND_UNA], eax |
; Stop retransmit timer |
mov [ebx + TCP_SOCKET.timer_retransmission], 0 |
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
; Unlock the socket |
pusha |
852,8 → 853,8 |
; (window info didnt change) The ACK is the biggest we've seen and we've seen exactly our rexmt threshold of them, |
; assume a packet has been dropped and retransmit it. Kludge snd_nxt & the congestion window so we send only this one packet. |
cmp [ebx + TCP_SOCKET.timer_retransmission], 0 ;;;; FIXME |
jg @f |
test [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
jz @f |
mov eax, [edx + TCP_header.AckNumber] |
cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
886,7 → 887,7 |
pop edx |
mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax |
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer |
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission ; turn off retransmission timer |
mov [ebx + TCP_SOCKET.t_rtt], 0 |
mov eax, [edx + TCP_header.AckNumber] |
mov [ebx + TCP_SOCKET.SND_NXT], eax |
1017,16 → 1018,16 |
mov eax, [ebx + TCP_SOCKET.SND_MAX] |
cmp eax, [edx + TCP_header.AckNumber] |
jne .more_data |
mov [ebx + TCP_SOCKET.timer_retransmission], 0 |
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT |
jmp .no_restart |
.more_data: |
cmp [ebx + TCP_SOCKET.timer_persist], 0 |
jne .no_restart |
test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist |
jnz .no_restart |
mov eax, [ebx + TCP_SOCKET.t_rxtcur] |
mov [ebx + TCP_SOCKET.timer_retransmission], eax |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_retransmission |
.no_restart: |
1140,6 → 1141,7 |
mov eax, ebx |
call SOCKET_is_disconnected |
mov [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
@@: |
mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 |
jmp .ack_processed |
1151,6 → 1153,7 |
mov eax, ebx |
call TCP_cancel_timers |
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
mov eax, ebx |
call SOCKET_is_disconnected |
jmp .ack_processed |
1164,6 → 1167,7 |
.ack_tw: |
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
jmp .drop_after_ack |
.reset_dupacks: ; We got a new ACK, reset duplicate ACK counter |
1209,6 → 1213,7 |
mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive |
lea eax, [ebx + STREAM_SOCKET.snd] |
call SOCKET_ring_create |
1272,7 → 1277,7 |
@@: |
.no_syn_ack: |
mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission |
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission ; disable retransmission timer |
push [edx + TCP_header.SequenceNumber] |
pop [ebx + TCP_SOCKET.IRS] |
1525,11 → 1530,13 |
mov eax, ebx |
call TCP_cancel_timers |
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
call SOCKET_is_disconnected |
jmp .final_processing |
.fin_timed: |
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait |
jmp .final_processing |
/kernel/branches/Kolibri-acpi/network/tcp_output.inc |
---|
93,7 → 93,7 |
jmp .no_force |
.no_zero_window: |
mov [eax + TCP_SOCKET.timer_persist], 0 |
and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist |
mov [eax + TCP_SOCKET.t_rxtshift], 0 |
.no_force: |
125,7 → 125,7 |
jnz @f |
; cancel pending retransmit |
mov [eax + TCP_SOCKET.timer_retransmission], 0 |
and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
; pull SND_NXT back to (closed) window, We will enter persist state below. |
push [eax + TCP_SOCKET.SND_UNA] |
268,11 → 268,12 |
cmp [eax + STREAM_SOCKET.snd.size], 0 ; Data ready to send? |
jne @f |
cmp [eax + TCP_SOCKET.timer_retransmission], 0 |
and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission |
jne @f |
cmp [eax + TCP_SOCKET.timer_persist], 0 ; Persist timer already expired? |
jne @f |
test [eax + TCP_SOCKET.timer_flags], timer_flag_persist ; Persist timer already expired? |
jnz @f |
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: Entering persist state\n" |
mov [eax + TCP_SOCKET.t_rxtshift], 0 |
512,19 → 513,19 |
@@: |
; set retransmission timer if not already set, and not doing an ACK or keepalive probe |
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
jnz .retransmit_set |
cmp [eax + TCP_SOCKET.timer_retransmission], 0 ;;;; FIXME |
ja .retransmit_set |
cmp edx, [eax + TCP_SOCKET.SND_UNA] ; edx is still [eax + TCP_SOCKET.SND_NXT] |
je .retransmit_set |
mov edx, [eax + TCP_SOCKET.t_rxtcur] |
mov [eax + TCP_SOCKET.timer_retransmission], edx |
or [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
cmp [eax + TCP_SOCKET.timer_persist], 0 |
jne .retransmit_set |
mov [eax + TCP_SOCKET.timer_persist], 0 |
test [eax + TCP_SOCKET.timer_flags], timer_flag_persist |
jz .retransmit_set |
and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist |
mov [eax + TCP_SOCKET.t_rxtshift], 0 |
.retransmit_set: |
593,11 → 594,12 |
pop eax |
mov [eax + TCP_SOCKET.timer_retransmission], TCP_time_re_min |
or [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
lea ecx, [eax + SOCKET.mutex] |
call mutex_unlock |
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: IP error\n" |
DEBUGF DEBUG_NETWORK_ERROR, "TCP_send: IP error\n" |
or eax, -1 |
ret |
609,7 → 611,7 |
lea ecx, [eax + SOCKET.mutex] |
call mutex_unlock |
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: sending failed\n" |
DEBUGF DEBUG_NETWORK_ERROR, "TCP_send: sending failed\n" |
or eax, -2 |
ret |
/kernel/branches/Kolibri-acpi/network/tcp_subr.inc |
---|
420,8 → 420,8 |
; First, check if retransmit timer is not set, retransmit and persist are mutually exclusive |
cmp [eax + TCP_SOCKET.timer_retransmission], 0 |
ja @f |
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
jnz .exit |
; calculate RTO |
push ebx |
436,7 → 436,7 |
; Start/restart persistance timer. |
TCPT_RANGESET [eax + TCP_SOCKET.timer_persist], ebx, TCP_time_pers_min, TCP_time_pers_max |
or [ebx + TCP_SOCKET.timer_flags], timer_flag_persist |
pop ebx |
cmp [eax + TCP_SOCKET.t_rxtshift], TCP_max_rxtshift |
443,6 → 443,7 |
jae @f |
inc [eax + TCP_SOCKET.t_rxtshift] |
@@: |
.exit: |
ret |
/kernel/branches/Kolibri-acpi/network/tcp_timer.inc |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Part of the TCP/IP network stack for KolibriOS ;; |
16,6 → 16,13 |
$Revision: 3143 $ |
timer_flag_retransmission = 1 shl 0 |
timer_flag_keepalive = 1 shl 1 |
timer_flag_2msl = 1 shl 2 |
timer_flag_persist = 1 shl 3 |
timer_flag_wait = 1 shl 4 |
;---------------------- |
; 160 ms timer |
;---------------------- |
27,17 → 34,16 |
mov ebx, net_sockets |
.loop: |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
test ebx, ebx |
jz .exit |
cmp [ebx + SOCKET.Domain], AF_INET4 |
jne .loop |
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
jne .loop |
test [ebx + TCP_SOCKET.t_flags], TF_DELACK |
jz .loop |
and [ebx + TCP_SOCKET.t_flags], not (TF_DELACK) |
push ebx |
58,7 → 64,7 |
;---------------------- |
; 640 ms timer |
;---------------------- |
macro TCP_timer_640ms { |
macro TCP_timer_640ms { ; TODO: implement timed wait timer! |
local .loop |
local .exit |
68,7 → 74,7 |
add [TCP_sequence_num], 64000 |
; scan through all the active TCP sockets, decrementing ALL timers |
; timers do not have the chance to wrap because the keepalive timer will kill the socket when it expires |
; When a timer reaches zero, we'll check wheter it was active or not |
mov eax, net_sockets |
.loop: |
84,8 → 90,11 |
jne .loop |
inc [eax + TCP_SOCKET.t_idle] |
dec [eax + TCP_SOCKET.timer_retransmission] |
jnz .check_more2 |
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission |
jz .check_more2 |
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: Retransmission timer expired\n", eax |
96,6 → 105,8 |
.check_more2: |
dec [eax + TCP_SOCKET.timer_keepalive] |
jnz .check_more3 |
test [eax + TCP_SOCKET.timer_flags], timer_flag_keepalive |
jz .check_more3 |
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: Keepalive expired\n", eax |
125,6 → 136,8 |
.check_more3: |
dec [eax + TCP_SOCKET.timer_timed_wait] |
jnz .check_more5 |
test [eax + TCP_SOCKET.timer_flags], timer_flag_2msl |
jz .check_more5 |
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: 2MSL timer expired\n", eax |
131,6 → 144,8 |
.check_more5: |
dec [eax + TCP_SOCKET.timer_persist] |
jnz .loop |
test [eax + TCP_SOCKET.timer_flags], timer_flag_persist |
jz .loop |
DEBUGF DEBUG_NETWORK_VERBOSE, "socket %x: persist timer expired\n", eax |
152,17 → 167,6 |
TCP_cancel_timers: |
push eax edi |
mov [eax + TCP_SOCKET.timer_flags], 0 |
lea edi, [eax + TCP_SOCKET.timer_retransmission] |
xor eax, eax |
stosd |
stosd |
stosd |
stosd |
stosd |
pop edi eax |
ret |
/kernel/branches/Kolibri-acpi/network/udp.inc |
---|
29,8 → 29,8 |
align 4 |
uglobal |
UDP_PACKETS_TX rd MAX_NET_DEVICES |
UDP_PACKETS_RX rd MAX_NET_DEVICES |
UDP_PACKETS_TX rd NET_DEVICES_MAX |
UDP_PACKETS_RX rd NET_DEVICES_MAX |
endg |
45,7 → 45,7 |
xor eax, eax |
mov edi, UDP_PACKETS_TX |
mov ecx, 2*MAX_NET_DEVICES |
mov ecx, 2*NET_DEVICES_MAX |
rep stosd |
} |