/kernel/branches/net/network/IPv4.inc |
---|
653,6 → 653,94 |
ret |
;------------------------------------------------------------------ |
; |
; IPv4_output_raw |
; |
; IN: eax = socket ptr |
; ecx = data length |
; esi = data ptr |
; |
; OUT: / |
; |
;------------------------------------------------------------------ |
align 4 |
IPv4_output_raw: |
DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax |
cmp ecx, 1480 ;;;;; |
jg .too_large |
sub esp, 8 |
push esi eax |
call ARP_IP_to_MAC |
test eax, 0xffff0000 ; error bits |
jnz .arp_error |
.continue: |
push ebx ; push the mac |
push ax |
call IPv4_dest_to_dev |
inc [IP_PACKETS_TX+edi] |
mov ebx, [NET_DRV_LIST+edi] |
lea eax, [ebx + ETH_DEVICE.mac] |
mov edx, esp |
mov ecx, [esp + 6+4] |
add ecx, IPv4_Packet.DataOrOptional |
mov di, ETHER_IPv4 |
call ETH_output |
jz .error |
add esp, 6 ; pop the mac |
mov dword[esp+4+4], edx |
mov dword[esp+4+4+4], eax |
pop eax esi |
;; todo: check socket options if we should add header, or just compute checksum |
push edi ecx |
rep movsb |
pop ecx edi |
; [edi + IPv4_Packet.VersionAndIHL] ; IPv4, normal length (no Optional header) |
; [edi + IPv4_Packet.TypeOfService] ; nothing special, just plain ip packet |
; [edi + IPv4_Packet.TotalLength] |
; [edi + IPv4_Packet.TotalLength] ; internet byte order |
; [edi + IPv4_Packet.FlagsAndFragmentOffset] |
mov [edi + IPv4_Packet.HeaderChecksum], 0 |
; [edi + IPv4_Packet.TimeToLive] ; ttl shl 8 + protocol |
; [edi + IPv4_Packet.Protocol] |
; [edi + IPv4_Packet.Identification] ; fragment id |
; [edi + IPv4_Packet.SourceAddress] |
; [edi + IPv4_Packet.DestinationAddress] |
IPv4_checksum edi ;;;; todo: checksum for IP packet with options! |
add edi, IPv4_Packet.DataOrOptional |
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx |
call [ebx + NET_DEVICE.transmit] |
ret |
.error: |
add esp, 6 |
.arp_error: |
add esp, 8+4+4 |
.too_large: |
DEBUGF 1,"IPv4_output_raw: Failed\n" |
sub edi, edi |
ret |
;-------------------------------------------------------- |
; |
; |
/kernel/branches/net/network/icmp.inc |
---|
132,9 → 132,11 |
; |
; IN: Pointer to buffer in [esp] |
; size of buffer in [esp+4] |
; pointer to device struct in ebx |
; ICMP Packet size in ecx |
; pointer to ICMP Packet data in edx |
; ebx = pointer to device struct |
; ecx = ICMP Packet size |
; edx = ptr to ICMP Packet data |
; esi = ipv4 source address |
; edi = ipv4 dest address |
; OUT: / |
; |
;----------------------------------------------------------------- |
141,16 → 143,14 |
align 4 |
ICMP_input: |
;;; TODO: works only on pure ethernet right now ! |
;;; TODO: check checksum! |
DEBUGF 1,"ICMP_Handler - start\n" |
DEBUGF 1,"ICMP_input - start\n" |
cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request? |
jne .check_sockets |
;;; TODO: check checksum! |
DEBUGF 1,"ICMP_input - echo request\n" |
DEBUGF 1,"ICMP_Handler - echo request\n" |
mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply |
mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum |
211,43 → 211,47 |
.check_sockets: |
; TODO: validate the header & checksum. |
; Look for an open ICMP socket |
; esi = sender ip |
mov esi, net_sockets |
mov ebx, net_sockets |
.try_more: |
mov ax , [edx + ICMP_Packet.Identifier] |
; mov ax , [edx + ICMP_Packet.Identifier] |
.next_socket: |
mov esi, [esi + SOCKET.NextPtr] |
or esi, esi |
mov ebx, [ebx + SOCKET.NextPtr] |
or ebx, ebx |
jz .dump |
cmp [esi + SOCKET.Type], IP_PROTO_ICMP |
cmp [ebx + SOCKET.Domain], AF_INET4 |
jne .next_socket |
cmp [esi + ICMP_SOCKET.Identifier], ax |
cmp [ebx + SOCKET.Type], SOCK_RAW |
jne .next_socket |
call IPv4_dest_to_dev |
cmp edi,-1 |
je .dump |
inc [ICMP_PACKETS_RX+edi] |
cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP |
jne .next_socket |
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi |
cmp [ebx + IP_SOCKET.RemoteIP], esi |
jne .next_socket |
lea ebx, [esi + SOCKET.lock] |
; cmp [esi + ICMP_SOCKET.Identifier], ax |
; jne .next_socket |
; call IPv4_dest_to_dev |
; cmp edi,-1 |
; je .dump |
; inc [ICMP_PACKETS_RX+edi] |
DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx |
mov eax, ebx |
add ebx, SOCKET.lock |
call wait_mutex |
; Now, assign data to socket. We have socket address in esi. |
; We have ICMP Packet in edx |
; number of bytes in ecx |
mov eax, esi |
pop esi |
add esp, 4 |
sub edx, esi |
mov edi, edx |
mov esi, edx |
jmp SOCKET_input |
.dump: |
DEBUGF 1,"ICMP_Handler - dumping\n" |
278,6 → 282,8 |
push esi edi edx |
mov ebx, [eax + IP_SOCKET.LocalIP] |
mov eax, [eax + IP_SOCKET.RemoteIP] |
add ecx, ICMP_Packet.Data |
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL |
shr edx, 16 |
327,6 → 333,57 |
;----------------------------------------------------------------- |
; |
; ICMP_output |
; |
; IN: eax = socket ptr |
; ecx = data length |
; esi = data offset |
; |
;----------------------------------------------------------------- |
align 4 |
ICMP_output_raw: |
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx |
push edx |
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL |
shr edx, 16 |
mov ebx, [eax + IP_SOCKET.LocalIP] |
mov eax, [eax + IP_SOCKET.RemoteIP] |
call IPv4_output |
jz .exit |
pop esi |
push edx |
push eax |
push edi ecx |
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi |
rep movsb |
pop ecx edi |
mov [edi + ICMP_Packet.Checksum], 0 |
mov esi, edi |
xor edx, edx |
call checksum_1 |
call checksum_2 |
mov [edi + ICMP_Packet.Checksum], dx |
DEBUGF 1,"Sending ICMP Packet\n" |
call [ebx + NET_DEVICE.transmit] |
ret |
.exit: |
DEBUGF 1,"Creating ICMP Packet failed\n" |
add esp, 4 |
ret |
;----------------------------------------------------------------- |
; |
; ICMP_API |
; |
; This function is called by system function 75 |
/kernel/branches/net/network/socket.inc |
---|
317,6 → 317,9 |
cmp edx, IP_PROTO_TCP |
je .tcp |
cmp edx, SOCK_RAW |
je .raw |
.no_inet4: |
ret |
340,12 → 343,41 |
pop eax |
mov [eax + SOCKET.snd_proc], SOCKET_send_udp |
mov [eax + SOCKET.rcv_proc], SOCKET_receive_udp |
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
ret |
.raw: |
; test esi, esi |
; jz .ip |
cmp esi, IP_PROTO_ICMP |
je .icmp |
ret |
; .ip: |
; push eax |
; init_queue (eax + SOCKET_QUEUE_LOCATION) |
; pop eax |
; |
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip |
; mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
; |
; ret |
.icmp: |
push eax |
init_queue (eax + SOCKET_QUEUE_LOCATION) |
pop eax |
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp |
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram |
ret |
;----------------------------------------------------------------- |
; |
; SOCKET_bind |
426,7 → 458,7 |
align 4 |
SOCKET_connect: |
DEBUGF 1,"socket_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi |
DEBUGF 1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi |
call SOCKET_num_to_ptr |
jz s_error |
447,6 → 479,9 |
cmp [eax + SOCKET.Type], IP_PROTO_TCP |
je .tcp |
cmp [eax + SOCKET.Type], SOCK_RAW |
je .raw |
jmp s_error |
.udp: |
497,7 → 532,14 |
mov dword [esp+32], 0 ; success! |
ret |
.raw: |
push dword [edx + 4] |
pop dword [eax + IP_SOCKET.RemoteIP] |
mov dword [esp+32], 0 ; success! |
ret |
;----------------------------------------------------------------- |
; |
; SOCKET_listen |
510,7 → 552,7 |
align 4 |
SOCKET_listen: |
DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n", ecx, edx |
DEBUGF 1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx |
call SOCKET_num_to_ptr |
jz s_error |
550,7 → 592,7 |
align 4 |
SOCKET_accept: |
DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi |
DEBUGF 1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi |
call SOCKET_num_to_ptr |
jz s_error |
601,7 → 643,7 |
align 4 |
SOCKET_close: |
DEBUGF 1,"socket_close: socknum: %u\n", ecx |
DEBUGF 1,"SOCKET_close: socknum: %u\n", ecx |
call SOCKET_num_to_ptr |
jz s_error |
658,11 → 700,10 |
jmp [eax + SOCKET.rcv_proc] |
align 4 |
SOCKET_receive_udp: |
SOCKET_receive_dgram: |
DEBUGF 1,"type: UDP\n" |
DEBUGF 1,"SOCKET_receive: DGRAM\n" |
mov ebx, esi |
mov edi, edx ; addr to buffer |
705,7 → 746,7 |
align 4 |
SOCKET_receive_tcp: |
DEBUGF 1,"type: TCP\n" |
DEBUGF 1,"SOCKET_receive: TCP\n" |
mov ecx, esi |
mov edi, edx |
733,7 → 774,7 |
align 4 |
SOCKET_send: |
DEBUGF 1,"SOCKET_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi |
DEBUGF 1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi |
call SOCKET_num_to_ptr |
jz s_error |
741,11 → 782,10 |
jmp [eax + SOCKET.snd_proc] |
align 4 |
SOCKET_send_udp: |
DEBUGF 1,"type: UDP\n" |
DEBUGF 1,"SOCKET_send: UDP\n" |
mov ecx, esi |
mov esi, edx |
759,7 → 799,7 |
align 4 |
SOCKET_send_tcp: |
DEBUGF 1,"type: TCP\n" |
DEBUGF 1,"SOCKET_send: TCP\n" |
push eax |
mov ecx, esi |
774,8 → 814,33 |
ret |
;align 4 |
;SOCKET_send_ip: |
; |
; DEBUGF 1,"type: IP\n" |
; |
; mov ecx, esi |
; mov esi, edx |
; |
; call IPv4_output_raw |
; |
; mov dword [esp+32], eax |
; ret |
align 4 |
SOCKET_send_icmp: |
DEBUGF 1,"SOCKET_send: ICMP\n" |
mov ecx, esi |
call ICMP_output_raw |
mov dword [esp+32], 0 |
ret |
;----------------------------------------------------------------- |
; |
; SOCKET_get_options |
991,13 → 1056,13 |
add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full |
DEBUGF 1,"Queued packet successfully\n" |
DEBUGF 1,"SOCKET_input: queued packet successfully\n" |
add esp, socket_queue_entry.size |
mov [eax + SOCKET.lock], 0 |
jmp SOCKET_notify_owner |
.full: |
DEBUGF 2,"Socket %x is full!\n", eax |
DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax |
mov [eax + SOCKET.lock], 0 |
call kernel_free |
add esp, 8 |
1049,7 → 1114,7 |
.copy: |
mov edi, [eax + RING_BUFFER.write_ptr] |
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi |
DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi |
push ecx |
shr ecx, 1 |
1087,7 → 1152,7 |
jmp .copy |
.full: |
DEBUGF 2,"Ring buffer is full!\n" |
DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n" |
xor ecx, ecx |
ret |
1116,7 → 1181,7 |
.copy: |
mov esi, [eax + RING_BUFFER.read_ptr] |
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi |
DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi |
push ecx |
shr ecx, 1 |
jnc .nb |
1334,7 → 1399,7 |
lea ebx, [eax + SOCKET.lock] |
call wait_mutex |
DEBUGF 1, "freeing socket..\n" |
DEBUGF 1, "SOCKET_free: freeing socket..\n" |
cmp [eax + SOCKET.Domain], AF_INET4 |
jnz .no_tcp |
1352,7 → 1417,7 |
mov ebx, [eax + SOCKET.NextPtr] |
mov eax, [eax + SOCKET.PrevPtr] |
DEBUGF 1, "linking socket %x to socket %x\n", eax, ebx |
DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx |
test eax, eax |
jz @f |
1367,7 → 1432,7 |
call kernel_free |
pop ebx |
DEBUGF 1, "socket is gone!\n" |
DEBUGF 1, "SOCKET_free: success!\n" |
.error: |
ret |