Subversion Repositories Kolibri OS

Rev

Rev 7679 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7679 Rev 7682
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2019. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2019. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  UDP.INC                                                        ;;
6
;;  UDP.INC                                                        ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
8
;;  Part of the TCP/IP network stack for KolibriOS                 ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
$Revision: 7679 $
17
$Revision: 7682 $
18
 
18
 
19
 
19
 
20
struct  UDP_header
20
struct  UDP_header
21
 
21
 
22
        SourcePort              dw  ?
22
        SourcePort              dw  ?
23
        DestinationPort         dw  ?
23
        DestinationPort         dw  ?
24
        Length                  dw  ?  ; Length of (UDP Header + Data)
24
        Length                  dw  ?  ; Length of (UDP Header + Data)
25
        Checksum                dw  ?
25
        Checksum                dw  ?
26
 
26
 
27
ends
27
ends
28
 
28
 
29
 
29
 
30
uglobal
30
uglobal
31
align 4
31
align 4
32
 
32
 
33
        UDP_packets_tx        rd  NET_DEVICES_MAX
33
        UDP_packets_tx          rd  NET_DEVICES_MAX
34
        UDP_packets_rx         rd  NET_DEVICES_MAX
34
        UDP_packets_rx          rd  NET_DEVICES_MAX
35
 
35
 
36
endg
36
endg
37
 
37
 
38
 
38
 
39
;-----------------------------------------------------------------;
39
;-----------------------------------------------------------------;
40
;                                                                 ;
40
;                                                                 ;
41
; udp_init: This function resets all UDP variables                ;
41
; udp_init: This function resets all UDP variables                ;
42
;                                                                 ;
42
;                                                                 ;
43
;-----------------------------------------------------------------;
43
;-----------------------------------------------------------------;
44
macro   udp_init {
44
macro   udp_init {
45
 
45
 
46
        xor     eax, eax
46
        xor     eax, eax
47
        mov     edi, UDP_packets_tx
47
        mov     edi, UDP_packets_tx
48
        mov     ecx, 2*NET_DEVICES_MAX
48
        mov     ecx, 2*NET_DEVICES_MAX
49
        rep stosd
49
        rep stosd
50
}
50
}
51
 
51
 
52
 
52
 
53
macro   udp_checksum    IP1, IP2  { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
53
macro   udp_checksum    IP1, IP2  { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
54
 
54
 
55
; Pseudoheader
55
; Pseudoheader
56
        mov     edx, IP_PROTO_UDP
56
        mov     edx, IP_PROTO_UDP
57
 
57
 
58
        add     dl, byte[IP1+1]
58
        add     dl, byte[IP1+1]
59
        adc     dh, byte[IP1+0]
59
        adc     dh, byte[IP1+0]
60
        adc     dl, byte[IP1+3]
60
        adc     dl, byte[IP1+3]
61
        adc     dh, byte[IP1+2]
61
        adc     dh, byte[IP1+2]
62
 
62
 
63
        adc     dl, byte[IP2+1]
63
        adc     dl, byte[IP2+1]
64
        adc     dh, byte[IP2+0]
64
        adc     dh, byte[IP2+0]
65
        adc     dl, byte[IP2+3]
65
        adc     dl, byte[IP2+3]
66
        adc     dh, byte[IP2+2]
66
        adc     dh, byte[IP2+2]
67
 
67
 
68
        adc     dl, cl ; byte[esi+UDP_header.Length+1]
68
        adc     dl, cl ; byte[esi+UDP_header.Length+1]
69
        adc     dh, ch ; byte[esi+UDP_header.Length+0]
69
        adc     dh, ch ; byte[esi+UDP_header.Length+0]
70
 
70
 
71
; Done with pseudoheader, now do real header
71
; Done with pseudoheader, now do real header
72
        adc     dl, byte[esi+UDP_header.SourcePort+1]
72
        adc     dl, byte[esi+UDP_header.SourcePort+1]
73
        adc     dh, byte[esi+UDP_header.SourcePort+0]
73
        adc     dh, byte[esi+UDP_header.SourcePort+0]
74
 
74
 
75
        adc     dl, byte[esi+UDP_header.DestinationPort+1]
75
        adc     dl, byte[esi+UDP_header.DestinationPort+1]
76
        adc     dh, byte[esi+UDP_header.DestinationPort+0]
76
        adc     dh, byte[esi+UDP_header.DestinationPort+0]
77
 
77
 
78
        adc     dl, byte[esi+UDP_header.Length+1]
78
        adc     dl, byte[esi+UDP_header.Length+1]
79
        adc     dh, byte[esi+UDP_header.Length+0]
79
        adc     dh, byte[esi+UDP_header.Length+0]
80
 
80
 
81
        adc     edx, 0
81
        adc     edx, 0
82
 
82
 
83
; Done with header, now do data
83
; Done with header, now do data
84
        push    esi
84
        push    esi
85
        movzx   ecx, [esi+UDP_header.Length]
85
        movzx   ecx, [esi+UDP_header.Length]
86
        rol     cx , 8
86
        rol     cx , 8
87
        sub     cx , sizeof.UDP_header
87
        sub     cx , sizeof.UDP_header
88
        add     esi, sizeof.UDP_header
88
        add     esi, sizeof.UDP_header
89
 
89
 
90
        call    checksum_1
90
        call    checksum_1
91
        call    checksum_2
91
        call    checksum_2
92
        pop     esi
92
        pop     esi
93
 
93
 
94
        add     [esi+UDP_header.Checksum], dx   ; this final instruction will set or clear ZF :)
94
        add     [esi+UDP_header.Checksum], dx   ; this final instruction will set or clear ZF :)
95
 
95
 
96
}
96
}
97
 
97
 
98
 
98
 
99
;-----------------------------------------------------------------;
99
;-----------------------------------------------------------------;
100
;                                                                 ;
100
;                                                                 ;
101
; udp_input: Inject the UDP data in the application sockets.      ;
101
; udp_input: Inject the UDP data in the application sockets.      ;
102
;                                                                 ;
102
;                                                                 ;
103
;   IN: [esp] = ptr to buffer                                     ;
103
;   IN: [esp] = ptr to buffer                                     ;
104
;       ebx = ptr to device struct                                ;
104
;       ebx = ptr to device struct                                ;
105
;       ecx = UDP packet size                                     ;
105
;       ecx = UDP packet size                                     ;
106
;       edx = ptr to IPv4 header                                  ;
106
;       edx = ptr to IPv4 header                                  ;
107
;       esi = ptr to UDP packet data                              ;
107
;       esi = ptr to UDP packet data                              ;
108
;       edi = interface number*4                                  ;
108
;       edi = interface number*4                                  ;
109
;                                                                 ;
109
;                                                                 ;
110
;  OUT: /                                                         ;
110
;  OUT: /                                                         ;
111
;                                                                 ;
111
;                                                                 ;
112
;-----------------------------------------------------------------;
112
;-----------------------------------------------------------------;
113
align 4
113
align 4
114
udp_input:
114
udp_input:
115
 
115
 
116
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
116
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: size=%u\n", ecx
117
 
117
 
118
        ; First validate, checksum
118
        ; First validate, checksum
119
 
119
 
120
        neg     [esi + UDP_header.Checksum]     ; substract checksum from 0
120
        neg     [esi + UDP_header.Checksum]     ; substract checksum from 0
121
        jz      .no_checksum                    ; if checksum is zero, it is considered valid
121
        jz      .no_checksum                    ; if checksum is zero, it is considered valid
122
 
122
 
123
        ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
123
        ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
124
 
124
 
125
        mov     eax, edx
125
        mov     eax, edx
126
        udp_checksum (eax+IPv4_header.SourceAddress), (eax+IPv4_header.DestinationAddress)
126
        udp_checksum (eax+IPv4_header.SourceAddress), (eax+IPv4_header.DestinationAddress)
127
        jnz     .checksum_mismatch
127
        jnz     .checksum_mismatch
128
 
128
 
129
  .no_checksum:
129
  .no_checksum:
130
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: checksum ok\n"
130
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: checksum ok\n"
131
 
131
 
132
        ; Convert length to little endian
132
        ; Convert length to little endian
133
 
133
 
134
        rol     [esi + UDP_header.Length], 8
134
        rol     [esi + UDP_header.Length], 8
135
 
135
 
136
        ; Look for a socket where
136
        ; Look for a socket where
137
        ; IP Packet UDP Destination Port = local Port
137
        ; IP Packet UDP Destination Port = local Port
138
        ; IP Packet SA = Remote IP
138
        ; IP Packet SA = Remote IP
139
 
139
 
140
        pusha
140
        pusha
141
        mov     ecx, socket_mutex
141
        mov     ecx, socket_mutex
142
        call    mutex_lock
142
        call    mutex_lock
143
        popa
143
        popa
144
 
144
 
145
        mov     cx, [esi + UDP_header.SourcePort]
145
        mov     cx, [esi + UDP_header.SourcePort]
146
        mov     dx, [esi + UDP_header.DestinationPort]
146
        mov     dx, [esi + UDP_header.DestinationPort]
147
        mov     eax, net_sockets
147
        mov     eax, net_sockets
148
  .next_socket:
148
  .next_socket:
149
        mov     eax, [eax + SOCKET.NextPtr]
149
        mov     eax, [eax + SOCKET.NextPtr]
150
        or      eax, eax
150
        or      eax, eax
151
        jz      .unlock_dump
151
        jz      .unlock_dump
152
 
152
 
153
        cmp     [eax + SOCKET.Domain], AF_INET4
153
        cmp     [eax + SOCKET.Domain], AF_INET4
154
        jne     .next_socket
154
        jne     .next_socket
155
 
155
 
156
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
156
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
157
        jne     .next_socket
157
        jne     .next_socket
158
 
158
 
159
        cmp     [eax + UDP_SOCKET.LocalPort], dx
159
        cmp     [eax + UDP_SOCKET.LocalPort], dx
160
        jne     .next_socket
160
        jne     .next_socket
161
 
161
 
162
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax
162
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: socket=%x\n", eax
163
 
163
 
164
        pusha
164
        pusha
165
        mov     ecx, socket_mutex
165
        mov     ecx, socket_mutex
166
        call    mutex_unlock
166
        call    mutex_unlock
167
        popa
167
        popa
168
 
168
 
169
        ;;; TODO: when packet is processed, check more sockets?!
169
        ;;; TODO: when packet is processed, check more sockets?!
170
 
170
 
171
; FIXME: check remote IP if possible
171
; FIXME: check remote IP if possible
172
;
172
;
173
;        cmp     [eax + IP_SOCKET.RemoteIP], 0xffffffff
173
;        cmp     [eax + IP_SOCKET.RemoteIP], 0xffffffff
174
;        je      @f
174
;        je      @f
175
;        cmp     [eax + IP_SOCKET.RemoteIP],
175
;        cmp     [eax + IP_SOCKET.RemoteIP],
176
;        jne     .next_socket
176
;        jne     .next_socket
177
;       @@:
177
;       @@:
178
 
178
 
179
        cmp     [eax + UDP_SOCKET.RemotePort], 0
179
        cmp     [eax + UDP_SOCKET.RemotePort], 0
180
        je      .updateport
180
        je      .updateport
181
 
181
 
182
        cmp     [eax + UDP_SOCKET.RemotePort], cx
182
        cmp     [eax + UDP_SOCKET.RemotePort], cx
183
        jne     .dump
183
        jne     .dump
184
 
184
 
185
        pusha
185
        pusha
186
        lea     ecx, [eax + SOCKET.mutex]
186
        lea     ecx, [eax + SOCKET.mutex]
187
        call    mutex_lock
187
        call    mutex_lock
188
        popa
188
        popa
189
 
189
 
190
  .updatesock:
190
  .updatesock:
191
        inc     [UDP_packets_rx + edi]
191
        inc     [UDP_packets_rx + edi]
192
 
192
 
193
        movzx   ecx, [esi + UDP_header.Length]
193
        movzx   ecx, [esi + UDP_header.Length]
194
        sub     ecx, sizeof.UDP_header
194
        sub     ecx, sizeof.UDP_header
195
        add     esi, sizeof.UDP_header
195
        add     esi, sizeof.UDP_header
196
 
196
 
197
        jmp     socket_input
197
        jmp     socket_input
198
 
198
 
199
  .updateport:
199
  .updateport:
200
        pusha
200
        pusha
201
        lea     ecx, [eax + SOCKET.mutex]
201
        lea     ecx, [eax + SOCKET.mutex]
202
        call    mutex_lock
202
        call    mutex_lock
203
        popa
203
        popa
204
 
204
 
205
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
205
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
206
        mov     [eax + UDP_SOCKET.RemotePort], cx
206
        mov     [eax + UDP_SOCKET.RemotePort], cx
207
        jmp     .updatesock
207
        jmp     .updatesock
208
 
208
 
209
  .unlock_dump:
209
  .unlock_dump:
210
        pusha
210
        pusha
211
        mov     ecx, socket_mutex
211
        mov     ecx, socket_mutex
212
        call    mutex_unlock
212
        call    mutex_unlock
213
        popa
213
        popa
214
 
214
 
215
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
215
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: no socket found\n"
216
        jmp     .dump
216
        jmp     .dump
217
 
217
 
218
  .checksum_mismatch:
218
  .checksum_mismatch:
219
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
219
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: checksum mismatch\n"
220
 
220
 
221
  .dump:
221
  .dump:
222
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: dumping\n"
222
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_input: dumping\n"
223
        call    net_buff_free
223
        call    net_buff_free
224
        ret
224
        ret
225
 
225
 
226
 
226
 
227
 
227
 
228
;-----------------------------------------------------------------;
228
;-----------------------------------------------------------------;
229
;                                                                 ;
229
;                                                                 ;
230
; udp_output: Create an UDP packet.                               ;
230
; udp_output: Create an UDP packet.                               ;
231
;                                                                 ;
231
;                                                                 ;
232
;  IN:  eax = socket pointer                                      ;
232
;  IN:  eax = socket pointer                                      ;
233
;       ecx = number of bytes to send                             ;
233
;       ecx = number of bytes to send                             ;
234
;       esi = pointer to data                                     ;
234
;       esi = pointer to data                                     ;
235
;                                                                 ;
235
;                                                                 ;
236
; OUT:  eax = -1 on error                                         ;
236
; OUT:  eax = -1 on error                                         ;
237
;                                                                 ;
237
;                                                                 ;
238
;-----------------------------------------------------------------;
238
;-----------------------------------------------------------------;
239
 
239
 
240
align 4
240
align 4
241
udp_output:
241
udp_output:
242
 
242
 
243
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: socket=%x bytes=%u data_ptr=%x\n", eax, ecx, esi
243
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: socket=%x bytes=%u data_ptr=%x\n", eax, ecx, esi
244
 
244
 
245
        mov     dx, [eax + UDP_SOCKET.RemotePort]
245
        mov     dx, [eax + UDP_SOCKET.RemotePort]
246
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: remote port=%x, ", dx    ; FIXME: find a way to print big endian values with debugf
246
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: remote port=%x, ", dx    ; FIXME: find a way to print big endian values with debugf
247
        rol     edx, 16
247
        rol     edx, 16
248
        mov     dx, [eax + UDP_SOCKET.LocalPort]
248
        mov     dx, [eax + UDP_SOCKET.LocalPort]
249
        DEBUGF  DEBUG_NETWORK_VERBOSE, "local port=%x\n", dx
249
        DEBUGF  DEBUG_NETWORK_VERBOSE, "local port=%x\n", dx
250
 
250
 
251
        sub     esp, 4                                          ; Data ptr will be placed here
251
        sub     esp, 4                                          ; Data ptr will be placed here
252
        push    edx esi
252
        push    edx esi
253
        mov     ebx, [eax + IP_SOCKET.device]
253
        mov     ebx, [eax + IP_SOCKET.device]
254
        mov     edx, [eax + IP_SOCKET.LocalIP]
254
        mov     edx, [eax + IP_SOCKET.LocalIP]
255
        mov     edi, [eax + IP_SOCKET.RemoteIP]
255
        mov     edi, [eax + IP_SOCKET.RemoteIP]
256
        mov     al, [eax + IP_SOCKET.ttl]
256
        mov     al, [eax + IP_SOCKET.ttl]
257
        mov     ah, IP_PROTO_UDP
257
        mov     ah, IP_PROTO_UDP
258
        add     ecx, sizeof.UDP_header
258
        add     ecx, sizeof.UDP_header
259
        call    ipv4_output
259
        call    ipv4_output
260
        jz      .fail
260
        jz      .fail
261
        mov     [esp + 8], eax                                  ; pointer to buffer start
261
        mov     [esp + 8], eax                                  ; pointer to buffer start
262
 
262
 
263
        mov     [edi + UDP_header.Length], cx
263
        mov     [edi + UDP_header.Length], cx
264
        rol     [edi + UDP_header.Length], 8
264
        rol     [edi + UDP_header.Length], 8
265
 
265
 
266
        pop     esi
266
        pop     esi
267
        push    edi ecx
267
        push    edi ecx
268
        sub     ecx, sizeof.UDP_header
268
        sub     ecx, sizeof.UDP_header
269
        add     edi, sizeof.UDP_header
269
        add     edi, sizeof.UDP_header
270
        shr     ecx, 2
270
        shr     ecx, 2
271
        rep movsd
271
        rep movsd
272
        mov     ecx, [esp]
272
        mov     ecx, [esp]
273
        and     ecx, 3
273
        and     ecx, 3
274
        rep movsb
274
        rep movsb
275
        pop     ecx edi
275
        pop     ecx edi
276
 
276
 
277
        pop     dword [edi + UDP_header.SourcePort]
277
        pop     dword [edi + UDP_header.SourcePort]
278
 
278
 
279
; Checksum
279
; Checksum
280
        mov     esi, edi
280
        mov     esi, edi
281
        mov     [edi + UDP_header.Checksum], 0
281
        mov     [edi + UDP_header.Checksum], 0
282
        udp_checksum (edi-4), (edi-8)                           ; FIXME: IPv4 packet could have options..
282
        udp_checksum (edi-4), (edi-8)                           ; FIXME: IPv4 packet could have options..
283
 
283
 
284
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: sending with device %x\n", ebx
284
        DEBUGF  DEBUG_NETWORK_VERBOSE, "UDP_output: sending with device %x\n", ebx
285
        call    [ebx + NET_DEVICE.transmit]
285
        call    [ebx + NET_DEVICE.transmit]
286
        test    eax, eax
286
        test    eax, eax
287
        jnz     @f
287
        jnz     @f
288
        call    net_ptr_to_num4
288
        call    net_ptr_to_num4
289
        inc     [UDP_packets_tx + edi]
289
        inc     [UDP_packets_tx + edi]
290
       @@:
290
       @@:
291
 
291
 
292
        ret
292
        ret
293
 
293
 
294
  .fail:
294
  .fail:
295
        DEBUGF  DEBUG_NETWORK_ERROR, "UDP_output: failed\n"
295
        DEBUGF  DEBUG_NETWORK_ERROR, "UDP_output: failed\n"
296
        add     esp, 4+4+8
296
        add     esp, 4+4+8
297
        or      eax, -1
297
        or      eax, -1
298
        ret
298
        ret
299
 
299
 
300
 
300
 
301
 
301
 
302
 
302
 
303
;-----------------------------------------------------------------;
303
;-----------------------------------------------------------------;
304
;                                                                 ;
304
;                                                                 ;
305
; udp_connect                                                     ;
305
; udp_connect                                                     ;
306
;                                                                 ;
306
;                                                                 ;
307
;   IN: eax = socket pointer                                      ;
307
;   IN: eax = socket pointer                                      ;
308
;                                                                 ;
308
;                                                                 ;
309
;  OUT: eax = 0 on success                                        ;
309
;  OUT: eax = 0 on success                                        ;
310
;       eax = -1 on error                                         ;
310
;       eax = -1 on error                                         ;
311
;       ebx = error code on error                                 ;
311
;       ebx = error code on error                                 ;
312
;                                                                 ;
312
;                                                                 ;
313
;-----------------------------------------------------------------;
313
;-----------------------------------------------------------------;
314
align 4
314
align 4
315
udp_connect:
315
udp_connect:
316
 
316
 
317
        test    [eax + SOCKET.state], SS_ISCONNECTED
317
        test    [eax + SOCKET.state], SS_ISCONNECTED
318
        jz      @f
318
        jz      @f
319
        call    udp_disconnect
319
        call    udp_disconnect
320
  @@:
320
  @@:
321
 
321
 
322
        push    eax edx
322
        push    eax edx
323
        lea     ecx, [eax + SOCKET.mutex]
323
        lea     ecx, [eax + SOCKET.mutex]
324
        call    mutex_lock
324
        call    mutex_lock
325
        pop     edx eax
325
        pop     edx eax
326
 
326
 
327
; Fill in remote port and IP
327
; Fill in remote port and IP
328
        pushw   [edx + 2]
328
        pushw   [edx + 2]
329
        pop     [eax + UDP_SOCKET.RemotePort]
329
        pop     [eax + UDP_SOCKET.RemotePort]
330
 
330
 
331
        pushd   [edx + 4]
331
        pushd   [edx + 4]
332
        pop     [eax + UDP_SOCKET.RemoteIP]
332
        pop     [eax + UDP_SOCKET.RemoteIP]
333
 
333
 
334
; Find route to host
334
; Find route to host
335
        pusha
335
        pusha
336
        push    eax
336
        push    eax
337
        mov     ebx, [eax + UDP_SOCKET.device]
337
        mov     ebx, [eax + UDP_SOCKET.device]
338
        mov     edx, [eax + UDP_SOCKET.LocalIP]
338
        mov     edx, [eax + UDP_SOCKET.LocalIP]
339
        mov     eax, [eax + UDP_SOCKET.RemoteIP]
339
        mov     eax, [eax + UDP_SOCKET.RemoteIP]
340
        call    ipv4_route
340
        call    ipv4_route
341
        test    eax, eax
341
        test    eax, eax
342
        jz      .enoroute
342
        jz      .enoroute
343
        pop     eax
343
        pop     eax
344
        mov     ebx, [net_device_list + edi]
344
        mov     ebx, [net_device_list + edi]
345
        mov     [eax + UDP_SOCKET.device], ebx
345
        mov     [eax + UDP_SOCKET.device], ebx
346
        mov     [eax + UDP_SOCKET.LocalIP], edx
346
        mov     [eax + UDP_SOCKET.LocalIP], edx
347
        popa
347
        popa
348
 
348
 
349
; Find a local port, if user didnt define one
349
; Find a local port, if user didnt define one
350
        cmp     [eax + UDP_SOCKET.LocalPort], 0
350
        cmp     [eax + UDP_SOCKET.LocalPort], 0
351
        jne     @f
351
        jne     @f
352
        call    socket_find_port
352
        call    socket_find_port
353
       @@:
353
       @@:
354
 
354
 
355
        push    eax
355
        push    eax
356
        lea     ecx, [eax + SOCKET.mutex]
356
        lea     ecx, [eax + SOCKET.mutex]
357
        call    mutex_unlock
357
        call    mutex_unlock
358
        pop     eax
358
        pop     eax
359
 
359
 
360
        call    socket_is_connected
360
        call    socket_is_connected
361
 
361
 
362
        xor     eax, eax
362
        xor     eax, eax
363
        ret
363
        ret
364
 
364
 
365
  .enoroute:
365
  .enoroute:
366
        pop     eax
366
        pop     eax
-
 
367
 
-
 
368
        push    eax
-
 
369
        lea     ecx, [eax + SOCKET.mutex]
-
 
370
        call    mutex_unlock
-
 
371
        pop     eax
-
 
372
 
367
        popa
373
        popa
368
        xor     eax, eax
374
        xor     eax, eax
369
        dec     eax
375
        dec     eax
370
        mov     ebx, EADDRNOTAVAIL
376
        mov     ebx, EADDRNOTAVAIL
371
        ret
377
        ret
372
 
378
 
373
 
379
 
374
;-----------------------------------------------------------------;
380
;-----------------------------------------------------------------;
375
;                                                                 ;
381
;                                                                 ;
376
; UDP_disconnect                                                  ;
382
; UDP_disconnect                                                  ;
377
;                                                                 ;
383
;                                                                 ;
378
;   IN: eax = socket pointer                                      ;
384
;   IN: eax = socket pointer                                      ;
379
;                                                                 ;
385
;                                                                 ;
380
;  OUT: eax = socket pointer                                      ;
386
;  OUT: eax = socket pointer                                      ;
381
;                                                                 ;
387
;                                                                 ;
382
;-----------------------------------------------------------------;
388
;-----------------------------------------------------------------;
383
align 4
389
align 4
384
udp_disconnect:
390
udp_disconnect:
385
 
391
 
386
        ; TODO: remove the pending received data
392
        ; TODO: remove the pending received data
387
 
393
 
388
        call    socket_is_disconnected
394
        call    socket_is_disconnected
389
 
395
 
390
        ret
396
        ret
391
 
397
 
392
 
398
 
393
 
399
 
394
 
400
 
395
 
401
 
396
;-----------------------------------------------------------------;
402
;-----------------------------------------------------------------;
397
;                                                                 ;
403
;                                                                 ;
398
; UDP_api: Part of system function 76                             ;
404
; UDP_api: Part of system function 76                             ;
399
;                                                                 ;
405
;                                                                 ;
400
;  IN: bl = subfunction number in bl                              ;
406
;  IN: bl = subfunction number in bl                              ;
401
;      bh = device number in bh                                   ;
407
;      bh = device number in bh                                   ;
402
;      ecx, edx, .. depends on subfunction                        ;
408
;      ecx, edx, .. depends on subfunction                        ;
403
;                                                                 ;
409
;                                                                 ;
404
; OUT: depends on subfunction                                     ;
410
; OUT: depends on subfunction                                     ;
405
;                                                                 ;
411
;                                                                 ;
406
;-----------------------------------------------------------------;
412
;-----------------------------------------------------------------;
407
align 4
413
align 4
408
udp_api:
414
udp_api:
409
 
415
 
410
        movzx   eax, bh
416
        movzx   eax, bh
411
        shl     eax, 2
417
        shl     eax, 2
412
 
418
 
413
        test    bl, bl
419
        test    bl, bl
414
        jz      .packets_tx     ; 0
420
        jz      .packets_tx     ; 0
415
        dec     bl
421
        dec     bl
416
        jz      .packets_rx     ; 1
422
        jz      .packets_rx     ; 1
417
 
423
 
418
  .error:
424
  .error:
419
        mov     eax, -1
425
        mov     eax, -1
420
        ret
426
        ret
421
 
427
 
422
  .packets_tx:
428
  .packets_tx:
423
        mov     eax, [UDP_packets_tx + eax]
429
        mov     eax, [UDP_packets_tx + eax]
424
        ret
430
        ret
425
 
431
 
426
  .packets_rx:
432
  .packets_rx:
427
        mov     eax, [UDP_packets_rx + eax]
433
        mov     eax, [UDP_packets_rx + eax]
428
        ret
434
        ret