/kernel/branches/net/network/ARP.inc |
---|
17,7 → 17,7 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 983 $ |
$Revision$ |
ARP_NO_ENTRY equ 0 |
26,7 → 26,7 |
ARP_RESPONSE_TIMEOUT equ 3 |
ARP_REQUEST_TTL = 20 ; in seconds |
ARP_ENTRY_TTL = 30 ; in seconds |
ARP_ENTRY_TTL = 600 ; in seconds |
ETHER_ARP equ 0x0608 |
135,8 → 135,10 |
mov ebx, [IP_LIST+edx] |
and ebx, [SUBNET_LIST+edx] |
mov ecx, eax |
and ecx, [SUBNET_LIST+edx] |
cmp ecx, ebx |
je .local |
146,12 → 148,13 |
.local: |
; try to find it on the list |
mov ecx, [NumARP] |
test ecx, ecx |
jz .not_in_list |
mov esi, ARPTable + ARP_ENTRY.IP |
.scan_loop: |
scasd |
jz .found_it |
add esi, ARP_ENTRY.size - 4 |
cmp [esi], eax |
je .found_it |
add esi, ARP_ENTRY.size |
loop .scan_loop |
.not_in_list: |
177,7 → 180,8 |
ret |
.found_it: |
DEBUGF 1,"Found MAC! (%u-%u-%u-%u-%u-%u)\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2 |
add esi, ARP_ENTRY.MAC |
DEBUGF 1,"Found MAC! (%x-%x-%x-%x-%x-%x)\n",[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2 |
movzx eax, word [esi] |
mov ebx, [esi+2] |
221,35 → 225,31 |
cmp edi, -1 |
je .exit |
mov word [edi + ARP_Packet.HardwareType], 0x0100 ;Ethernet |
mov word [edi + ARP_Packet.ProtocolType], 0x0008 ;IP |
mov byte [edi + ARP_Packet.HardwareSize], 6 ;MAC-addr length |
mov byte [edi + ARP_Packet.ProtocolSize], 4 ;IP-addr length |
mov word [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ;Request |
mov ecx, eax |
mov [edi + ARP_Packet.HardwareType], 0x0100 ;Ethernet |
mov [edi + ARP_Packet.ProtocolType], 0x0008 ;IP |
mov [edi + ARP_Packet.HardwareSize], 6 ;MAC-addr length |
mov [edi + ARP_Packet.ProtocolSize], 4 ;IP-addr length |
mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ;Request |
add edi, ARP_Packet.SenderMAC ; sendermac |
lea esi, [edx + ETH_DEVICE.mac] ; |
lea esi, [ebx + ETH_DEVICE.mac] ; |
movsw ; |
movsd ; |
pop eax ; |
stosd ; |
mov eax, -1 ; destmac |
stosd ; |
stosw ; |
pop eax |
stosd ; |
xor eax, eax ; destmac |
movsw ; |
movsw ; |
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx |
pop eax |
movsd ; |
push edx ecx |
jmp ETH_Sender |
DEBUGF 1,"ARP Packet for device %x created successfully\n", edx |
call esi |
inc [ARP_PACKETS_TX+4*edi] |
ret |
.exit: |
add esp, 8 |
DEBUGF 1,"Create ARP Packet - failed\n" |
278,30 → 278,31 |
.timer_loop: |
movsx esi, word [ebx + ARP_ENTRY.TTL] |
cmp esi, 0xFFFFFFFF |
cmp [ebx + ARP_ENTRY.TTL], 0xFFFF |
je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
test esi, esi |
cmp [ebx + ARP_ENTRY.TTL], 0 |
jnz .timer_loop_end_with_dec ;if TTL!=0 |
; Ok, TTL is 0 |
;if Status==AWAITING_RESPONSE and TTL==0 |
;then we have to change it to ARP_RESPONSE_TIMEOUT |
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
cmp [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
jne @f |
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
mov [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
mov [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
jmp .timer_loop_end |
@@: |
;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
mov esi, dword[NumARP] |
mov esi, [NumARP] |
sub esi, ecx ;esi=index of entry, will be deleted |
push ebx ecx |
call ARP_del_entry |
pop ecx ebx |
jmp .timer_loop_end |
308,7 → 309,7 |
.timer_loop_end_with_dec: |
dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
dec [ebx + ARP_ENTRY.TTL] ;decrease TTL |
.timer_loop_end: |
338,6 → 339,8 |
align 4 |
ARP_add_entry: |
DEBUGF 1,"ARP add entry: " |
mov ecx, [NumARP] |
test ecx, ecx |
jz .add |
355,7 → 358,7 |
cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF ; static entry |
jne .notstatic |
cmp dword[esp + ARP_ENTRY.TTL], 0xFFFF |
jne .exit |
jne .error |
.notstatic: |
mov ebx, [NumARP] |
369,14 → 372,13 |
mov ecx, [NumARP] |
cmp ecx, ARP_TABLE_SIZE |
jge .full |
jge .error |
.add: |
push ecx |
imul ecx, ARP_ENTRY.size |
lea edi, [ecx + ARPTable] |
lea esi, [esp + 4] |
lea esi, [esp + 8] |
mov ecx, ARP_ENTRY.size/2 |
repz movsw |
384,17 → 386,19 |
pop eax |
.exit: |
pop ebx ; return addr |
add esp, ARP_ENTRY.size |
DEBUGF 1,"Exiting\n" |
jmp ebx |
add esp, 14 |
ret |
.error: |
.full: |
DEBUGF 1,"error! \n" |
mov eax, -1 |
jmp .exit |
;--------------------------------------------------------------------------- |
; |
; ARP_del_entry |
407,6 → 411,13 |
align 4 |
ARP_del_entry: |
DEBUGF 1,"ARP del entry %u, total entrys: %u\n", esi, [NumARP] |
cmp esi, [NumARP] |
jge .error |
DEBUGF 1,"deleting the entry..\n" |
imul esi, ARP_ENTRY.size |
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
416,10 → 427,10 |
lea esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry |
shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
cld |
rep movsw |
dec [NumARP] ;decrease arp-entries counter |
.error: |
ret |
449,35 → 460,41 |
cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE ; Is this a reply packet? |
jne .maybe_request |
DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\ |
[edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1, |
mov ecx, [NumARP] |
test ecx, ecx |
jz .exit |
mov eax, [esp] |
mov eax, [eax + ARP_Packet.SenderIP] |
mov eax, [edx + ARP_Packet.SenderIP] |
mov esi, ARPTable+ARP_ENTRY.IP |
.loop: |
scasd |
jz .gotit |
add esi, ARP_ENTRY.size-4 |
cmp [esi], eax |
je .gotit |
add esi, ARP_ENTRY.size |
loop .loop |
jmp .exit |
.gotit: |
cmp [esi-4+ARP_ENTRY.Status], 0x0300 ;if it is a static entry, dont touch it |
DEBUGF 1,"ARP_Handler - found matching entry\n" |
cmp [esi+ARP_ENTRY.Status], 0x0300 ;if it is a static entry, dont touch it |
je .exit |
mov [esi-4+ARP_ENTRY.Status], ARP_VALID_MAPPING |
mov [esi+ARP_ENTRY.TTL-4], ARP_ENTRY_TTL |
DEBUGF 1,"ARP_Handler - updating entry\n" |
mov ebx, [esp] |
mov eax, dword [ebx + ARP_Packet.SenderMAC] |
mov dword [esi+ARP_ENTRY.MAC-4], eax |
mov ax , word [ebx + ARP_Packet.SenderMAC + 4] |
mov word [esi+ARP_ENTRY.MAC-4+4], ax |
mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING |
mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL |
mov eax, dword [edx + ARP_Packet.SenderMAC] |
mov dword [esi+ARP_ENTRY.MAC], eax |
mov ax , word [edx + ARP_Packet.SenderMAC + 4] |
mov word [esi+ARP_ENTRY.MAC+4], ax |
jmp .exit |
489,7 → 506,7 |
jne .exit |
call ETH_struc2dev |
DEBUGF 1,"ARP Packet came from device: %u\n", edi |
DEBUGF 1,"ARP Request packet through device: %u\n", edi |
inc [ARP_PACKETS_RX+4*edi] |
cmp edi, -1 |
jz .exit |
536,6 → 553,8 |
; mov ax , ETHER_ARP |
; stosw |
DEBUGF 1,"ARP_Handler - Sending reply \n" |
jmp ETH_Sender ; And send it! |
.exit: |
542,7 → 561,7 |
call kernel_free |
add esp, 4 ; pop (balance stack) |
DEBUGF 1,"ARP_Handler - fail\n" |
DEBUGF 1,"ARP_Handler - exiting\n" |
ret |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/IPv4.inc |
---|
16,7 → 16,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 922 $ |
$Revision$ |
; IP underlying protocols numbers |
507,11 → 507,13 |
align 4 |
IPv4_create_packet: |
DEBUGF 1,"Create IPv4 Packet\n" |
DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx |
cmp ecx, 1514 |
cmp ecx, 1480 |
jg .exit_ |
push ecx eax ebx dx di |
cmp eax, -1 |
je .broadcast ; If it is broadcast, just send |
518,18 → 520,10 |
call ARP_IP_to_MAC |
cmp eax, -1 |
jne .found |
je .not_found |
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
; TODO: QUEUE! |
or edi, -1 |
ret |
.found: |
push ebx |
push ax |
push ebx |
jmp .send |
537,19 → 531,17 |
push word -1 |
push dword -1 |
.send: |
push ecx eax ebx dx di |
call IPv4_dest_to_dev |
inc [IP_PACKETS_TX+4*edi] |
mov edi, [ETH_DRV_LIST + 4*edi] |
lea eax, [edi + ETH_DEVICE.mac] |
lea ebx, [esp+16] |
mov ecx, [esp+12] |
mov edx, [ETH_DRV_LIST + 4*edi] |
lea eax, [edx + ETH_DEVICE.mac] |
mov ebx, esp |
mov ecx, [esp+18] ;; 18 or 22 ?? |
add ecx, IPv4_Packet.DataOrOptional |
mov edx, edi ;;; |
mov di , ETHER_IPv4 |
call ETH_create_Packet ; TODO: figure out a way to make this work with other protocols too |
add esp, 6 |
cmp edi, -1 |
je .exit |
578,12 → 570,14 |
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx |
add esp, 6 |
ret |
.not_found: |
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" |
; TODO: QUEUE! |
.exit: |
add esp, 16+6 |
add esp, 16 |
.exit_: |
DEBUGF 1,"Create IPv4 Packet - failed\n" |
or edi, -1 |
591,6 → 585,7 |
;--------------------------------------------------------------------------- |
; |
; IPv4_dest_to_dev |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/IPv6.inc |
---|
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/ethernet.inc |
---|
14,7 → 14,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 983 $ |
$Revision$ |
MAX_ETH_DEVICES equ MAX_NET_DEVICES |
ETH_QUEUE_SIZE equ 16 |
352,11 → 352,11 |
; device number in edx |
; protocol in di |
; |
; OUT: edi is -1 on error, pointer to buffer otherwise ;; TODO: XCHG EDX AND EBX output parameters |
; OUT: edi is -1 on error, pointer to buffer otherwise |
; eax points to buffer start |
; ebx is size of complete buffer |
; ebx is pointer to device structure |
; ecx is unchanged (packet size of embedded data) |
; edx is pointer to device structure |
; edx is size of complete buffer |
; esi points to procedure wich needs to be called to send packet |
; |
;--------------------------------------------------------------------------- |
364,11 → 364,9 |
align 4 |
ETH_create_Packet: |
DEBUGF 1,"Creating Ethernet Packet:\n" |
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx |
cmp ecx, 60-ETH_FRAME.Data |
jl .exit |
cmp ecx, 1514-ETH_FRAME.Data |
cmp ecx, 1500 |
jg .exit |
push ecx di eax ebx edx |
394,25 → 392,34 |
stosw |
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start |
mov ebx, ecx ; Set ebx to complete buffer size |
mov edx, ecx ; Set ebx to complete buffer size |
pop ecx |
mov esi, ETH_Sender |
xor edx, edx ;;;; TODO: Fixme |
mov edx, [ETH_DRV_LIST + edx] |
xor ebx, ebx ;;;; TODO: Fixme |
mov ebx, [ETH_DRV_LIST + ebx] |
DEBUGF 1,"done: %x size:%u device:%x\n", eax, ebx, edx |
cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes |
jg .continue |
mov edx, 46 + ETH_FRAME.Data |
.continue: |
DEBUGF 1,"done: %x size:%u device:%x\n", eax, edx, ebx |
ret |
.pop_exit: |
DEBUGF 1,"Out of ram space!!\n" |
add esp, 18 |
or edi,-1 |
ret |
.exit: |
DEBUGF 1,"Packet too large!\n" |
or edi, -1 |
ret |
;--------------------------------------------------------------------------- |
; |
; ETH_API |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/icmp.inc |
---|
17,7 → 17,7 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 593 $ |
$Revision$ |
; ICMP types & codes |
214,7 → 214,7 |
.check_sockets: |
; TODO: validate the header & checksum. Discard buffer if error |
; TODO: validate the header & checksum. |
; Look for an open ICMP socket |
387,7 → 387,7 |
cmp edi, -1 |
je .exit |
DEBUGF 1,"full icmp packet size: %u\n", ebx |
DEBUGF 1,"full icmp packet size: %u\n", edx |
pop eax |
mov word [edi + ICMP_Packet.Type], ax ; Write both type and code bytes at once |
411,8 → 411,7 |
and cx , 3 |
rep movsb |
sub edi, ebx ;; TODO: find a better way to remember start of packet |
xchg ebx, edx |
sub edi, edx ;; TODO: find a better way to remember start of packet |
mov ecx, [ebx + ETH_DEVICE.transmit] |
push edx edi ecx |
DEBUGF 1,"Sending ICMP Packet\n" |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/queue.inc |
---|
12,7 → 12,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 983 $ |
$Revision$ |
struct queue |
.size dd ? |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/socket.inc |
---|
14,7 → 14,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 1019 $ |
$Revision$ |
align 4 |
struct SOCKET |
27,8 → 27,8 |
.Protocol dd ? ; ICMP/IPv4/ARP/ |
.LocalIP dd ? ; local IP address |
.RemoteIP dd ? ; remote IP address |
.LocalPort dw ? ; local port |
.RemotePort dw ? ; remote port |
.LocalPort dw ? ; local port (In INET byte order) |
.RemotePort dw ? ; remote port (IN INET byte order |
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) |
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) |
.rxDataCount dd ? ; rx data count |
130,6 → 130,7 |
; OUT: eax is socket num, -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_open: |
DEBUGF 1,"socket_open: domain: %u, type: %u",ecx, edx |
162,7 → 163,7 |
; OUT: 0 on success |
; |
;----------------------------------------------- |
align 4 |
socket_bind: |
DEBUGF 1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi |
175,51 → 176,32 |
jl s_error |
cmp word [edx], AF_INET4 |
je .af_inet4 |
jne s_error |
jmp s_error |
.af_inet4: |
cmp esi, 6 |
jl s_error |
mov ecx, [eax + SOCKET.Type] |
mov bx, word [edx + 2] |
rol bx,8 ;;; |
DEBUGF 1,"local port: %u ",bx |
DEBUGF 1,"local port: %x ",bx |
test bx, bx |
jnz .check_only |
jz .find_free |
mov bx , [last_UDP_port] |
call socket_check_port |
test bx, bx |
je s_error |
jmp .got_port |
.find_port_loop: |
inc bx |
inc [last_UDP_port] |
.find_free: |
.check_only: |
mov esi, net_sockets |
call socket_find_port |
test bx, bx |
je s_error |
.next_udp_socket: |
mov esi, [esi + SOCKET.NextPtr] |
or esi, esi |
jz .udp_port_ok |
cmp [esi + SOCKET.Type], IP_PROTO_UDP |
jne .next_udp_socket |
cmp [esi + SOCKET.LocalPort], bx |
jne .next_udp_socket |
cmp word [edx + 2], 0 |
jne s_error |
cmp bx, MAX_EPHEMERAL_PORT |
jle .find_port_loop |
mov [last_UDP_port], MIN_EPHEMERAL_PORT |
jmp s_error |
.udp_port_ok: |
.got_port: |
DEBUGF 1,"using port: %x ",bx |
mov word [eax + SOCKET.LocalPort], bx |
mov ebx, dword [edx + 4] |
246,7 → 228,6 |
; |
;----------------------------------------------- |
align 4 |
socket_connect: |
DEBUGF 1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi |
274,8 → 255,8 |
cmp [eax + SOCKET.Type], IP_PROTO_ICMP |
je .icmp |
; cmp [eax + SOCKET.Type], IP_PROTO_TCP |
; je .tcp |
cmp [eax + SOCKET.Type], IP_PROTO_TCP |
je .tcp |
jmp s_error |
282,14 → 263,11 |
.udp: |
mov bx , word [edx + 2] |
rol bx, 8 |
mov word [eax + SOCKET.RemotePort], bx |
DEBUGF 1,"remote port: %x ",bx |
DEBUGF 1,"remote port: %u ",bx |
mov ebx, dword [edx + 4] |
mov dword [eax + SOCKET.RemoteIP], ebx |
DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1 |
mov dword [esp+32],0 |
395,7 → 373,7 |
; OUT: eax is socket num, -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_listen: |
DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx |
432,8 → 410,7 |
; OUT: eax is socket num, -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_accept: |
DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi |
479,7 → 456,7 |
; OUT: eax is socket num, -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_close: |
DEBUGF 1,"Socket_close: socknum: %u\n",ecx |
495,8 → 472,8 |
cmp [eax + SOCKET.Type], IP_PROTO_ICMP |
je .icmp |
; cmp [eax + SOCKET.Type], IP_PROTO_TCP |
; je .tcp |
cmp [eax + SOCKET.Type], IP_PROTO_TCP |
je .tcp |
jmp s_error |
629,7 → 606,7 |
; OUT: eax is number of bytes copied, -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_recv: |
DEBUGF 1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi |
703,13 → 680,13 |
; |
; |
; IN: socket number in ecx |
; addr in edx |
; addrlen in esi |
; pointer to data in edx |
; datalength in esi |
; flags in edi |
; OUT: -1 on error |
; |
;----------------------------------------------- |
align 4 |
socket_send: |
DEBUGF 1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi |
718,6 → 695,13 |
or eax, eax |
jz s_error |
cmp word [eax + SOCKET.Domain], AF_INET4 |
je .af_inet4 |
jmp s_error |
.af_inet4: |
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET.Type]:4 |
cmp [eax + SOCKET.Type], IP_PROTO_UDP |
726,21 → 710,30 |
cmp [eax + SOCKET.Type], IP_PROTO_ICMP |
je .icmp |
; cmp [eax + SOCKET.Type], IP_PROTO_TCP |
; je .tcp |
cmp [eax + SOCKET.Type], IP_PROTO_TCP |
je .tcp |
jmp s_error |
.udp: |
DEBUGF 1,"type: UDP\n" |
DEBUGF 1,"type: UDP, " |
cmp [eax + SOCKET.LocalPort],0 |
jne .port_ok |
mov ecx, [eax + SOCKET.Type] |
call socket_find_port |
test bx, bx |
je s_error |
mov [eax + SOCKET.LocalPort], bx |
.port_ok: |
mov ecx, esi |
mov esi, edx |
mov edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once |
DEBUGF 1,"local port: %u, remote port:%u\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2 |
bswap edx ;;; |
rol edx, 16 ;;; |
DEBUGF 1,"local port: %x, remote port: %x\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2 |
mov ebx, [eax + SOCKET.LocalIP] |
mov eax, [eax + SOCKET.RemoteIP] |
781,10 → 774,177 |
;----------------------------------------------- |
; |
; SOCKET_find_free_port (local port) |
; |
; works with INET byte order |
; |
; IN: type in ecx (TCP/UDP) |
; OUT: bx = 0 on error, portnumber otherwise |
; |
;----------------------------------------------- |
align 4 |
socket_find_port: |
DEBUGF 1,"Socket_find_free_port, type: %u ",eax |
cmp ecx, IP_PROTO_UDP |
je .udp |
cmp ecx, IP_PROTO_TCP |
je .tcp |
.udp: |
mov bx, [last_UDP_port] |
je .continue |
.tcp: |
mov bx, [last_TCP_port] |
.continue: |
inc bx |
.check_only: |
mov esi, net_sockets |
.next_socket: |
mov esi, [esi + SOCKET.NextPtr] |
or esi, esi |
jz .port_ok |
cmp [esi + SOCKET.Type], ecx |
jne .next_socket |
rol bx, 8 |
cmp [esi + SOCKET.LocalPort], bx |
rol bx, 8 ; this doesnt change the zero flag, does it ? |
jne .next_socket |
cmp bx, MAX_EPHEMERAL_PORT |
jle .continue |
; todo: WRAP! |
; mov [last_UDP_port], MIN_EPHEMERAL_PORT |
.exit: |
xor ebx, ebx |
.port_ok: |
rol bx, 8 |
ret |
;----------------------------------------------- |
; |
; SOCKET_check_port (local port) |
; |
; works with INET byte order |
; |
; IN: type in ecx (TCP/UDP) |
; port to check in bx |
; OUT: bx = 0 on error, unchanged otherwise |
; |
;----------------------------------------------- |
align 4 |
socket_check_port: |
mov esi, net_sockets |
.next_socket: |
mov esi, [esi + SOCKET.NextPtr] |
or esi, esi |
jz .port_ok |
cmp [esi + SOCKET.Type], ecx |
jne .next_socket |
cmp [esi + SOCKET.LocalPort], bx |
jne .next_socket |
xor ebx, ebx |
.port_ok: |
ret |
;----------------------------------------------- |
; |
; SOCKET_internal_receiver |
; |
; Checks if any socket wants the received data |
; If so, update the socket |
; |
; IN: eax = socket number |
; ecx = number of bytes |
; esi = pointer to beginning of data |
; dx = Remote port (in INET byte order) |
; edi = IP address of sender |
; |
; OUT: xxx |
; |
;----------------------------------------------- |
align 4 |
socket_internal_receiver: |
DEBUGF 1,"internal socket receiver\n" |
lea ebx, [eax + SOCKET.lock] |
call wait_mutex |
mov [eax + SOCKET.RemotePort], dx ; update remote port number |
mov [eax + SOCKET.RemoteIP], edi |
mov edx, [eax + SOCKET.rxDataCount] ; get # of bytes already in buffer |
DEBUGF 1,"bytes already in socket: %u ", edx |
lea edi, [ecx + edx] ; check for buffer overflow |
cmp edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE ; |
jg .dump ; |
lea edi, [eax + SOCKET.rxData + edx] |
add [eax + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer |
DEBUGF 1,"adding %u bytes\n", ecx |
; copy the data across |
push cx |
shr ecx, 2 |
rep movsd |
pop cx |
and cx, 3 |
rep movsb |
DEBUGF 1,"socket updated\n" |
mov [eax + SOCKET.lock], 0 |
; flag an event to the application |
mov edx, [eax + SOCKET.PID] ; get socket owner PID |
mov ecx, 1 |
mov esi, TASK_DATA + TASKDATA.pid |
.next_pid: |
cmp [esi], edx |
je .found_pid |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next_pid |
ret |
.found_pid: |
shl ecx, 8 |
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
mov [check_idle_semaphore], 200 |
ret |
.dump: |
mov [eax + SOCKET.lock], 0 |
ret |
; Allocate memory for socket data and put new socket into the list |
; Newly created socket is initialized with calling PID and number and |
; put into beginning of list (which is a fastest way). |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/stack.inc |
---|
17,7 → 17,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 983 $ |
$Revision$ |
uglobal |
last_1sTick db ? |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/tcp.inc |
---|
15,7 → 15,7 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 1019 $ |
$Revision$ |
; TCP TCB states |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/branches/net/network/udp.inc |
---|
14,7 → 14,7 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision: 983 $ |
$Revision$ |
struct UDP_Packet |
44,7 → 44,6 |
; OUT: / |
; |
;----------------------------------------------------------------- |
align 4 |
UDP_init: |
72,117 → 71,67 |
; OUT: / |
; |
;----------------------------------------------------------------- |
align 4 |
UDP_handler: |
DEBUGF 1,"UDP_Handler\n" |
; TODO: First validate the header & checksum. Discard buffer if error |
; TODO: First validate the header & checksum! |
; Look for a socket where |
; IP Packet UDP Destination Port = local Port |
; IP Packet SA = Remote IP |
mov esi, net_sockets |
mov eax, net_sockets |
.try_more: |
mov ax , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header |
rol ax , 8 |
mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header |
.next_socket: |
mov esi, [esi + SOCKET.NextPtr] |
or esi, esi |
mov eax, [eax + SOCKET.NextPtr] |
or eax, eax |
jz .dump |
cmp [esi + SOCKET.Type], IP_PROTO_UDP |
cmp [eax + SOCKET.Domain], AF_INET4 |
jne .next_socket |
cmp [esi + SOCKET.LocalPort], ax |
cmp [eax + SOCKET.Type], IP_PROTO_UDP |
jne .next_socket |
cmp [eax + SOCKET.LocalPort], bx |
jne .next_socket |
; 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 [esi + SOCKET.RemoteIP], 0xffffffff |
je @f |
cmp [eax + SOCKET.RemoteIP], 0xffffffff |
je .ok1 |
mov eax, [esp] |
mov eax, [eax + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet |
cmp [esi + SOCKET.RemoteIP], eax |
mov ebx, [esp] |
mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet |
cmp [eax + SOCKET.RemoteIP], eax |
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination |
@@: |
DEBUGF 1,"Found valid UDP packet for socket %x\n", esi |
.ok1: |
; sub ecx, UDP_Packet.Data ; get # of bytes in ecx |
; mov eax, ecx |
mov bx, [edx + UDP_Packet.SourcePort] ; Remote port must be 0, or equal to sourceport of packet |
movzx ecx, [edx + UDP_Packet.Length] |
xchg cl , ch |
cmp [eax + SOCKET.RemotePort],0 |
je .ok2 |
; cmp ecx, eax ; If UDP packet size is bigger then IP packet told us, |
; jg .error ; Something must went wrong! |
cmp [eax + SOCKET.RemotePort], bx |
jne .dump |
lea ebx, [esi + SOCKET.lock] |
call wait_mutex |
.ok2: |
; 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 + UDP_Packet.SourcePort] ; get the UDP source port |
xchg al, ah |
mov [esi + SOCKET.RemotePort], ax |
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax |
lea esi, [edx + UDP_Packet.Data] |
movzx ecx, [edx + UDP_Packet.Length] |
rol cx , 8 |
sub cx , UDP_Packet.Data |
mov dx , bx |
; Now, copy data to socket. We have socket address as [eax + sockets]. |
; We have IP Packet in edx |
call socket_internal_receiver |
add edx, UDP_Packet.Data |
mov eax, [esi + SOCKET.rxDataCount] ; get # of bytes already in buffer |
DEBUGF 1,"bytes in socket: %u ", eax |
lea edi, [ecx + eax] ; check for buffer overflow |
cmp edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE ; |
jg .dump ; |
add [esi + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer |
DEBUGF 1,"adding %u bytes\n", ecx |
inc [UDP_PACKETS_RX] |
; ecx has count, edx points to data |
lea edi, [esi + eax + SOCKETHEADERSIZE] |
push esi |
push ecx |
mov esi, edx |
shr ecx, 2 |
rep movsd ; copy the data across |
pop ecx |
and ecx, 3 |
rep movsb |
pop esi |
DEBUGF 1,"UDP socket updated\n" |
mov [esi + SOCKET.lock], 0 |
; flag an event to the application |
mov eax, [esi + SOCKET.PID] ; get socket owner PID |
mov ecx, 1 |
mov esi, TASK_DATA + TASKDATA.pid |
.next_pid: |
cmp [esi], eax |
je .found_pid |
inc ecx |
add esi, 0x20 |
cmp ecx, [TASK_COUNT] |
jbe .next_pid |
jmp .dump |
.found_pid: |
shl ecx, 8 |
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
mov [check_idle_semaphore], 200 |
.dump: |
DEBUGF 1,"UDP_handler - dumping\n" |
DEBUGF 1,"Dumping UDP packet\n" |
call kernel_free |
add esp, 4 ; pop (balance stack) |
205,7 → 154,7 |
UDP_create_packet: |
DEBUGF 1,"Create UDP Packet\n" |
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx |
push edx esi |
216,7 → 165,7 |
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6 |
cmp edi, -1 |
je .exit |
je .fail |
mov byte[edi + UDP_Packet.Length], ch |
mov byte[edi + UDP_Packet.Length+1], cl |
234,17 → 183,15 |
pop edi |
pop ecx |
; bswap ecx ; convert little endian - big endian |
; rol ecx, 16 ; |
mov dword [edi + UDP_Packet.SourcePort], ecx ; notice: we write both port's at once |
mov [edi + UDP_Packet.Checksum], 0 |
; TODO: calculate checksum using Pseudo-header (However, using a 0 as checksum shouldnt generate any errors :) |
push ebx eax ; TODO: make this work on other protocols besides ethernet |
mov ebx,edx ; |
inc [UDP_PACKETS_TX] |
push edx eax ; TODO: make this work on other protocols besides ethernet |
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx ; |
jmp ETH_Sender ; |
251,8 → 198,13 |
.exit: |
ret |
.fail: |
; todo: queue the packet |
add esp, 8 |
ret |
;--------------------------------------------------------------------------- |
; |
; UDP_API |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |