Subversion Repositories Kolibri OS

Rev

Rev 3698 | Rev 3861 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  IPv4.INC                                                       ;;
7
;;                                                                 ;;
8
;;  Part of the TCP/IP network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;  Based on the work of [Johnny_B] and [smb]                      ;;
11
;;                                                                 ;;
12
;;    Written by hidnplayr@kolibrios.org                           ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
$Revision: 3515 $
20
 
21
MAX_FRAGMENTS                   = 64
22
 
23
struct  IPv4_header
24
 
25
        VersionAndIHL           db ?    ; Version[0-3 bits] and IHL(header length)[4-7 bits]
26
        TypeOfService           db ?    ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0]
27
        TotalLength             dw ?
28
        Identification          dw ?
29
        FlagsAndFragmentOffset  dw ?    ; Flags[0-2] and FragmentOffset[3-15]
30
        TimeToLive              db ?    ;
31
        Protocol                db ?
32
        HeaderChecksum          dw ?
33
        SourceAddress           dd ?
34
        DestinationAddress      dd ?
35
 
36
ends
37
 
38
struct  FRAGMENT_slot
39
 
40
        ttl                     dw ?    ; Time to live for this entry, 0 for empty slot's
41
        id                      dw ?    ; Identification field from IP header
42
        SrcIP                   dd ?    ; .. from IP header
43
        DstIP                   dd ?    ; .. from IP header
44
        ptr                     dd ?    ; Pointer to first packet
45
 
46
ends
47
 
48
struct  FRAGMENT_entry                  ; This structure will replace the ethernet header in fragmented ip packets
49
 
50
        PrevPtr                 dd ?    ; Pointer to previous fragment entry  (-1 for first packet)
51
        NextPtr                 dd ?    ; Pointer to next fragment entry (-1 for last packet)
52
        Owner                   dd ?    ; Pointer to structure of driver
53
                                rb 2    ; to match ethernet header size         ;;; FIXME
54
                                        ; Ip header begins here (we will need the IP header to re-construct the complete packet)
55
ends
56
 
57
 
3698 hidnplayr 58
uglobal
3545 hidnplayr 59
align 4
60
 
3600 hidnplayr 61
        IP_LIST                 rd NET_DEVICES_MAX
62
        SUBNET_LIST             rd NET_DEVICES_MAX
63
        DNS_LIST                rd NET_DEVICES_MAX
64
        GATEWAY_LIST            rd NET_DEVICES_MAX
65
        BROADCAST_LIST          rd NET_DEVICES_MAX
3545 hidnplayr 66
 
3600 hidnplayr 67
        IP_packets_tx           rd NET_DEVICES_MAX
68
        IP_packets_rx           rd NET_DEVICES_MAX
69
        IP_packets_dumped       rd NET_DEVICES_MAX
3545 hidnplayr 70
 
3600 hidnplayr 71
        FRAGMENT_LIST           rb MAX_FRAGMENTS * sizeof.FRAGMENT_slot
3698 hidnplayr 72
 
3545 hidnplayr 73
endg
74
 
75
 
76
;-----------------------------------------------------------------
77
;
78
; IPv4_init
79
;
80
;  This function resets all IP variables
81
;
82
;-----------------------------------------------------------------
83
macro   IPv4_init {
84
 
85
        xor     eax, eax
86
        mov     edi, IP_LIST
3600 hidnplayr 87
        mov     ecx, 7*NET_DEVICES_MAX + (sizeof.FRAGMENT_slot*MAX_FRAGMENTS)/4
3711 clevermous 88
        rep stosd
3545 hidnplayr 89
 
90
}
91
 
92
 
93
;-----------------------------------------------------------------
94
;
95
; Decrease TimeToLive of all fragment slots
96
;
97
;-----------------------------------------------------------------
98
macro IPv4_decrease_fragment_ttls {
99
 
100
local   .loop, .next
101
 
102
        mov     esi, FRAGMENT_LIST
103
        mov     ecx, MAX_FRAGMENTS
104
  .loop:
105
        cmp     [esi + FRAGMENT_slot.ttl], 0
106
        je      .next
107
        dec     [esi + FRAGMENT_slot.ttl]
108
        jz      .died
109
  .next:
110
        add     esi, sizeof.FRAGMENT_slot
111
        dec     ecx
112
        jnz     .loop
113
        jmp     .done
114
 
115
  .died:
3556 hidnplayr 116
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4 Fragment slot timed-out!\n"
3545 hidnplayr 117
;;; TODO: clear all entry's of timed-out slot
118
        jmp     .next
119
 
120
  .done:
121
}
122
 
123
 
124
 
125
macro IPv4_checksum ptr {
126
 
127
; This is the fast procedure to create or check an IP header without options
128
; To create a new checksum, the checksum field must be set to 0 before computation
129
; To check an existing checksum, leave the checksum as is, and it will be 0 after this procedure, if it was correct
130
 
131
        push    ebx
132
        xor     ebx, ebx
133
        add     bl, [ptr+1]
134
        adc     bh, [ptr+0]
135
 
136
        adc     bl, [ptr+3]
137
        adc     bh, [ptr+2]
138
 
139
        adc     bl, [ptr+5]
140
        adc     bh, [ptr+4]
141
 
142
        adc     bl, [ptr+7]
143
        adc     bh, [ptr+6]
144
 
145
        adc     bl, [ptr+9]
146
        adc     bh, [ptr+8]
147
 
148
; we skip 11th and 12th byte, they are the checksum bytes and should be 0 for re-calculation
149
 
150
        adc     bl, [ptr+13]
151
        adc     bh, [ptr+12]
152
 
153
        adc     bl, [ptr+15]
154
        adc     bh, [ptr+14]
155
 
156
        adc     bl, [ptr+17]
157
        adc     bh, [ptr+16]
158
 
159
        adc     bl, [ptr+19]
160
        adc     bh, [ptr+18]
161
 
162
        adc     ebx, 0
163
 
164
        push    ecx
165
        mov     ecx, ebx
166
        shr     ecx, 16
167
        and     ebx, 0xffff
168
        add     ebx, ecx
169
 
170
        mov     ecx, ebx
171
        shr     ecx, 16
172
        add     ebx, ecx
173
 
174
        not     bx
175
        jnz     .not_zero
176
        dec     bx
177
  .not_zero:
178
        xchg    bl, bh
179
        pop     ecx
180
 
181
        neg     word [ptr+10]           ; zero will stay zero so we just get the checksum
182
        add     word [ptr+10], bx       ;  , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
183
        pop     ebx
184
 
185
}
186
 
187
 
188
 
189
;-----------------------------------------------------------------
190
;
191
; IPv4_input:
192
;
193
;  Will check if IPv4 Packet isnt damaged
194
;  and call appropriate handler. (TCP/UDP/ICMP/..)
195
;
196
;  It will also re-construct fragmented packets
197
;
198
;  IN:  Pointer to buffer in [esp]
199
;       size of buffer in [esp+4]
200
;       pointer to device struct in ebx
201
;       pointer to IPv4 header in edx
202
;       size of IPv4 packet in ecx
203
;  OUT: /
204
;
205
;-----------------------------------------------------------------
206
align 4
207
IPv4_input:                                                     ; TODO: add IPv4 raw sockets support
208
 
3556 hidnplayr 209
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input, packet from: %u.%u.%u.%u ",\
3545 hidnplayr 210
        [edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
211
        [edx + IPv4_header.SourceAddress + 2]:1,[edx + IPv4_header.SourceAddress + 3]:1
3556 hidnplayr 212
        DEBUGF  DEBUG_NETWORK_VERBOSE, "to: %u.%u.%u.%u\n",\
3545 hidnplayr 213
        [edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
214
        [edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
215
 
216
;-------------------------------
217
; re-calculate the checksum
218
 
219
        IPv4_checksum edx
220
        jnz     .dump                                           ; if checksum isn't valid then dump packet
221
 
3556 hidnplayr 222
        DEBUGF  DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
3545 hidnplayr 223
 
224
;-----------------------------------
225
; Check if destination IP is correct
226
 
3643 hidnplayr 227
        call    NET_ptr_to_num4
3545 hidnplayr 228
 
229
        ; check if it matches local ip (Using RFC1122 strong end system model)
230
 
231
        mov     eax, [edx + IPv4_header.DestinationAddress]
232
        cmp     eax, [IP_LIST + edi]
233
        je      .ip_ok
234
 
235
        ; check for broadcast (IP or (not SUBNET))
236
 
237
        cmp     eax, [BROADCAST_LIST + edi]
238
        je      .ip_ok
239
 
240
        ; or a special broadcast (255.255.255.255)
241
 
242
        cmp     eax, 0xffffffff
243
        je      .ip_ok
244
 
245
        ; mayb