Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1171 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3251 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
1171 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  STACK.INC                                                      ;;
7
;;                                                                 ;;
1763 hidnplayr 8
;;  TCP/IP stack for KolibriOS                                     ;;
1171 hidnplayr 9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
1763 hidnplayr 12
;;     Some parts of code are based on the work of:                ;;
13
;;      Mike Hibbett (menuetos network stack)                      ;;
14
;;      Eugen Brasoveanu (solar os network stack and drivers)      ;;
15
;;      mike.dld (kolibrios socket code)                           ;;
1171 hidnplayr 16
;;                                                                 ;;
1763 hidnplayr 17
;;     TCP part is based on 4.4BSD                                 ;;
18
;;                                                                 ;;
1171 hidnplayr 19
;;          GNU GENERAL PUBLIC LICENSE                             ;;
20
;;             Version 2, June 1991                                ;;
21
;;                                                                 ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1159 hidnplayr 23
 
1206 hidnplayr 24
$Revision: 3459 $
1159 hidnplayr 25
 
26
uglobal
2366 hidnplayr 27
        net_10ms        dd ?
28
        net_tmr_count   dw ?
1159 hidnplayr 29
endg
30
 
2731 hidnplayr 31
MAX_NET_DEVICES         = 16
3360 hidnplayr 32
ARP_BLOCK               = 1             ; true or false
1159 hidnplayr 33
 
2731 hidnplayr 34
MIN_EPHEMERAL_PORT      = 49152
2995 hidnplayr 35
MIN_EPHEMERAL_PORT_N    = 0x00C0        ; same in Network byte order (FIXME)
2731 hidnplayr 36
MAX_EPHEMERAL_PORT      = 61000
2995 hidnplayr 37
MAX_EPHEMERAL_PORT_N    = 0x48EE        ; same in Network byte order (FIXME)
1159 hidnplayr 38
 
1514 hidnplayr 39
; Ethernet protocol numbers
2731 hidnplayr 40
ETHER_ARP               = 0x0608
41
ETHER_IPv4              = 0x0008
42
ETHER_IPv6              = 0xDD86
43
ETHER_PPP_DISCOVERY     = 0x6388
44
ETHER_PPP_SESSION       = 0x6488
1185 hidnplayr 45
 
2931 hidnplayr 46
; PPP protocol numbers
47
PPP_IPv4                = 0x2100
2964 hidnplayr 48
PPP_IPV6                = 0x5780
2931 hidnplayr 49
 
1514 hidnplayr 50
;Protocol family
2731 hidnplayr 51
AF_UNSPEC               = 0
3251 hidnplayr 52
AF_LOCAL                = 1
2731 hidnplayr 53
AF_INET4                = 2
54
AF_INET6                = 10
2931 hidnplayr 55
AF_PPP                  = 777
1159 hidnplayr 56
 
1514 hidnplayr 57
; Internet protocol numbers
2731 hidnplayr 58
IP_PROTO_IP             = 0
59
IP_PROTO_ICMP           = 1
60
IP_PROTO_TCP            = 6
61
IP_PROTO_UDP            = 17
1159 hidnplayr 62
 
2931 hidnplayr 63
; PPP protocol number
64
PPP_PROTO_ETHERNET      = 666
65
 
1200 hidnplayr 66
; Socket types
2731 hidnplayr 67
SOCK_STREAM             = 1
68
SOCK_DGRAM              = 2
69
SOCK_RAW                = 3
1200 hidnplayr 70
 
1514 hidnplayr 71
; Socket options
2731 hidnplayr 72
SO_ACCEPTCON            = 1 shl 0
73
SO_BROADCAST            = 1 shl 1
74
SO_DEBUG                = 1 shl 2
75
SO_DONTROUTE            = 1 shl 3
76
SO_KEEPALIVE            = 1 shl 4
77
SO_OOBINLINE            = 1 shl 5
78
SO_REUSEADDR            = 1 shl 6
79
SO_REUSEPORT            = 1 shl 7
80
SO_USELOOPBACK          = 1 shl 8
2877 hidnplayr 81
SO_BINDTODEVICE         = 1 shl 9
1159 hidnplayr 82
 
3257 hidnplayr 83
SO_BLOCK                = 1 shl 10    ; TO BE REMOVED
84
SO_NONBLOCK             = 1 shl 31
2994 hidnplayr 85
 
3459 hidnplayr 86
; Socket flags for user calls
87
MSG_PEEK                = 0x02
88
MSG_DONTWAIT            = 0x40
89
 
2877 hidnplayr 90
; Socket level
91
SOL_SOCKET              = 0
1885 hidnplayr 92
 
2877 hidnplayr 93
 
1773 hidnplayr 94
; Socket States
3257 hidnplayr 95
SS_NOFDREF              = 0x0001      ; no file table ref any more
96
SS_ISCONNECTED          = 0x0002      ; socket connected to a peer
97
SS_ISCONNECTING         = 0x0004      ; in process of connecting to peer
98
SS_ISDISCONNECTING      = 0x0008      ; in process of disconnecting
99
SS_CANTSENDMORE         = 0x0010      ; can't send more data to peer
100
SS_CANTRCVMORE          = 0x0020      ; can't receive more data from peer
101
SS_RCVATMARK            = 0x0040      ; at mark on input
102
SS_ISABORTING           = 0x0080      ; aborting fd references - close()
103
SS_RESTARTSYS           = 0x0100      ; restart blocked system calls
104
SS_ISDISCONNECTED       = 0x0800      ; socket disconnected from peer
1773 hidnplayr 105
 
3257 hidnplayr 106
SS_ASYNC                = 0x0100      ; async i/o notify
107
SS_ISCONFIRMING         = 0x0200      ; deciding to accept connection req
108
SS_MORETOCOME           = 0x0400
1773 hidnplayr 109
 
3257 hidnplayr 110
SS_BLOCKED              = 0x8000
1773 hidnplayr 111
 
3257 hidnplayr 112
 
2731 hidnplayr 113
SOCKET_MAXDATA          = 4096*32     ; must be 4096*(power of 2) where 'power of 2' is at least 8
1254 hidnplayr 114
 
1514 hidnplayr 115
; Network driver types
2914 hidnplayr 116
NET_TYPE_LOOPBACK       = 0
2731 hidnplayr 117
NET_TYPE_ETH            = 1
118
NET_TYPE_SLIP           = 2
1254 hidnplayr 119
 
2731 hidnplayr 120
MAX_backlog             = 20          ; maximum backlog for stream sockets
1254 hidnplayr 121
 
1716 hidnplayr 122
; Error Codes
2731 hidnplayr 123
ENOBUFS                 = 55
124
ECONNREFUSED            = 61
125
ECONNRESET              = 52
126
ETIMEDOUT               = 60
127
ECONNABORTED            = 53
1529 hidnplayr 128
 
2731 hidnplayr 129
; Api protocol numbers
130
API_ETH                 = 0
131
API_IPv4                = 1
132
API_ICMP                = 2
133
API_UDP                 = 3
134
API_TCP                 = 4
135
API_ARP                 = 5
136
API_PPPOE               = 6
3185 hidnplayr 137
API_IPv6                = 7
1716 hidnplayr 138
 
2924 hidnplayr 139
HWACC_TCP_IPv4          = 1 shl 0
140
 
2366 hidnplayr 141
struct  NET_DEVICE
1254 hidnplayr 142
 
2366 hidnplayr 143
        type            dd ?    ; Type field
144
        mtu             dd ?    ; Maximal Transmission Unit
145
        name            dd ?    ; Ptr to 0 terminated string
1519 hidnplayr 146
 
2366 hidnplayr 147
        unload          dd ?    ; Ptrs to driver functions
148
        reset           dd ?    ;
149
        transmit        dd ?    ;
1519 hidnplayr 150
 
2366 hidnplayr 151
        bytes_tx        dq ?    ; Statistics, updated by the driver
152
        bytes_rx        dq ?    ;
153
        packets_tx      dd ?    ;
154
        packets_rx      dd ?    ;
1519 hidnplayr 155
 
3346 hidnplayr 156
        state           dd ?    ; link state (0 = no link)
157
        hwacc           dd ?    ; bitmask stating enabled HW accelerations (offload engines)
1519 hidnplayr 158
 
2305 hidnplayr 159
ends
1529 hidnplayr 160
 
1254 hidnplayr 161
 
1514 hidnplayr 162
; Exactly as it says..
1318 hidnplayr 163
macro pseudo_random reg {
2366 hidnplayr 164
        add     reg, [esp]
165
        rol     reg, 5
166
        xor     reg, [timer_ticks]
167
        add     reg, [CPU_FREQ]
168
        imul    reg, 214013
169
        xor     reg, 0xdeadbeef
170
        rol     reg, 9
1514 hidnplayr 171
}
1318 hidnplayr 172
 
3249 hidnplayr 173
; Network to Hardware byte order (dword)
1543 hidnplayr 174
macro ntohd reg {
1318 hidnplayr 175
 
2366 hidnplayr 176
        rol     word reg, 8
177
        rol     dword reg, 16
178
        rol     word reg , 8
1514 hidnplayr 179
 
1318 hidnplayr 180
}
181
 
3249 hidnplayr 182
; Network to Hardware byte order (word)
1543 hidnplayr 183
macro ntohw reg {
1514 hidnplayr 184
 
2366 hidnplayr 185
        rol     word reg, 8
1514 hidnplayr 186
 
187
}
188
 
2382 hidnplayr 189
 
1159 hidnplayr 190
include "queue.inc"
1514 hidnplayr 191
 
2914 hidnplayr 192
include "loopback.inc"
1514 hidnplayr 193
include "ethernet.inc"
1719 hidnplayr 194
 
2931 hidnplayr 195
include "PPPoE.inc"
1514 hidnplayr 196
 
1187 hidnplayr 197
include "ARP.inc"
198
include "IPv4.inc"
3185 hidnplayr 199
include "IPv6.inc"
1514 hidnplayr 200
 
201
include "icmp.inc"
202
include "udp.inc"
1249 hidnplayr 203
include "tcp.inc"
1159 hidnplayr 204
 
1514 hidnplayr 205
include "socket.inc"
206
 
207
 
208
 
209
align 4
210
uglobal
211
 
2366 hidnplayr 212
        NET_RUNNING     dd  ?
213
        NET_DEFAULT     dd  ?
214
        NET_DRV_LIST    rd  MAX_NET_DEVICES
1514 hidnplayr 215
 
216
endg
217
 
218
 
1257 hidnplayr 219
;-----------------------------------------------------------------
1159 hidnplayr 220
;
221
; stack_init
222
;
223
;  This function calls all network init procedures
224
;
225
;  IN:  /
226
;  OUT: /
227
;
1257 hidnplayr 228
;-----------------------------------------------------------------
1159 hidnplayr 229
align 4
230
stack_init:
231
 
1514 hidnplayr 232
; Init the network drivers list
2366 hidnplayr 233
        xor     eax, eax
234
        mov     edi, NET_RUNNING
235
        mov     ecx, (MAX_NET_DEVICES + 2)
236
        rep     stosd
1514 hidnplayr 237
 
2960 hidnplayr 238
        PPPoE_init
1514 hidnplayr 239
 
2366 hidnplayr 240
        IPv4_init
2731 hidnplayr 241
;        IPv6_init
2366 hidnplayr 242
        ICMP_init
1514 hidnplayr 243
 
2366 hidnplayr 244
        ARP_init
245
        UDP_init
246
        TCP_init
1514 hidnplayr 247
 
2366 hidnplayr 248
        SOCKET_init
1514 hidnplayr 249
 
2366 hidnplayr 250
        mov     [net_tmr_count], 0
1159 hidnplayr 251
 
2366 hidnplayr 252
        ret
1159 hidnplayr 253
 
254
 
1257 hidnplayr 255
;-----------------------------------------------------------------
1159 hidnplayr 256
;
257
; stack_handler
258
;
1514 hidnplayr 259
;  This function is called in kernel loop
1159 hidnplayr 260
;
261
;  IN:  /
262
;  OUT: /
263
;
1257 hidnplayr 264
;-----------------------------------------------------------------
1159 hidnplayr 265
align 4
266
stack_handler:
267
 
2366 hidnplayr 268
        cmp     [NET_RUNNING], 0
269
        je      .exit
1159 hidnplayr 270
 
3459 hidnplayr 271
        cmp     [UDP_PACKETS_TX], 50
272
        jb      @f
273
        DEBUGF  1, "\n\nCRAP!\n\n"
274
        jmp     $
275
      @@:
276
 
2366 hidnplayr 277
        ; Test for 10ms tick
278
        mov     eax, [timer_ticks]
279
        cmp     eax, [net_10ms]
280
        je      .exit
281
        mov     [net_10ms], eax
1159 hidnplayr 282
 
2366 hidnplayr 283
        test    [net_10ms], 0x0f        ; 160ms
284
        jnz     .exit
1249 hidnplayr 285
 
2366 hidnplayr 286
        TCP_timer_160ms
1159 hidnplayr 287
 
2366 hidnplayr 288
        test    [net_10ms], 0x3f        ; 640ms
289
        jnz     .exit
1519 hidnplayr 290
 
2366 hidnplayr 291
        TCP_timer_640ms
292
        ARP_decrease_entry_ttls
293
        IPv4_decrease_fragment_ttls
1159 hidnplayr 294
 
295
  .exit:
2366 hidnplayr 296
        ret
1159 hidnplayr 297
 
298
 
1514 hidnplayr 299
 
3340 hidnplayr 300
align 4
301
NET_link_changed:
302
 
3388 hidnplayr 303
        DEBUGF  1,"NET_link_changed device=0x%x status=0x%x\n", ebx, [ebx + NET_DEVICE.state]
3359 hidnplayr 304
 
3340 hidnplayr 305
align 4
306
NET_send_event:
307
 
3346 hidnplayr 308
        DEBUGF  1,"NET_send_event\n"
309
 
3340 hidnplayr 310
; Send event to all applications
311
        push    edi ecx
312
        mov     edi, SLOT_BASE
313
        mov     ecx, [TASK_COUNT]
314
  .loop:
315
        add     edi, 256
316
        or      [edi + APPDATA.event_mask], EVENT_NETWORK2
317
        loop    .loop
318
        pop     ecx edi
319
 
320
;        call    change_task
321
 
322
        ret
323
 
324
 
325
 
1249 hidnplayr 326
;-----------------------------------------------------------------
327
;
2220 hidnplayr 328
; NET_add_device:
1514 hidnplayr 329
;
330
;  This function is called by the network drivers,
331
;  to register each running NIC to the kernel
332
;
333
;  IN:  Pointer to device structure in ebx
334
;  OUT: Device num in eax, -1 on error
335
;
336
;-----------------------------------------------------------------
337
align 4
338
NET_add_device:
339
 
2366 hidnplayr 340
        DEBUGF  1,"NET_Add_Device: %x\n", ebx   ;;; TODO: use mutex to lock net device list
1514 hidnplayr 341
 
3359 hidnplayr 342
        cmp     [NET_RUNNING], MAX_NET_DEVICES
2366 hidnplayr 343
        jae     .error
1514 hidnplayr 344
 
345
;----------------------------------
346
; Check if device is already listed
2366 hidnplayr 347
        mov     eax, ebx
348
        mov     ecx, MAX_NET_DEVICES    ; We need to check whole list because a device may be removed without re-organizing list
349
        mov     edi, NET_DRV_LIST
1514 hidnplayr 350
 
2366 hidnplayr 351
        repne   scasd                   ; See if device is already in the list
352
        jz      .error
1514 hidnplayr 353
 
354
;----------------------------
355
; Find empty slot in the list
2366 hidnplayr 356
        xor     eax, eax
357
        mov     ecx, MAX_NET_DEVICES
358
        mov     edi, NET_DRV_LIST
1514 hidnplayr 359
 
2366 hidnplayr 360
        repne   scasd
361
        jnz     .error
1514 hidnplayr 362
 
2366 hidnplayr 363
        sub     edi, 4
1514 hidnplayr 364
 
2220 hidnplayr 365
;-----------------------------
366
; Add device to the found slot
2366 hidnplayr 367
        mov     [edi], ebx              ; add device to list
1514 hidnplayr 368
 
2366 hidnplayr 369
        mov     eax, edi                ; Calculate device number in eax
370
        sub     eax, NET_DRV_LIST
371
        shr     eax, 2
1514 hidnplayr 372
 
2366 hidnplayr 373
        inc     [NET_RUNNING]           ; Indicate that one more network device is up and running
1514 hidnplayr 374
 
2366 hidnplayr 375
        cmp     eax, 1                  ; If it's the first network device, try to set it as default
376
        jne     @f
377
        push    eax
378
        call    NET_set_default
379
        pop     eax
2220 hidnplayr 380
       @@:
1514 hidnplayr 381
 
3340 hidnplayr 382
        call    NET_send_event
383
 
2366 hidnplayr 384
        DEBUGF  1,"Device number: %u\n", eax
385
        ret
1514 hidnplayr 386
 
2220 hidnplayr 387
  .error:
2366 hidnplayr 388
        or      eax, -1
389
        DEBUGF  2,"Adding network device failed\n"
390
        ret
1514 hidnplayr 391
 
392
 
393
 
2220 hidnplayr 394
;-----------------------------------------------------------------
395
;
396
; NET_set_default
397
;
398
;  API to set the default interface
399
;
400
;  IN:  Device num in eax
401
;  OUT: Device num in eax, -1 on error
402
;
403
;-----------------------------------------------------------------
404
align 4
405
NET_set_default:
1514 hidnplayr 406
 
2891 hidnplayr 407
        DEBUGF  1,"NET_set_default: device=%x\n", eax
1514 hidnplayr 408
 
2366 hidnplayr 409
        cmp     eax, MAX_NET_DEVICES
410
        jae     .error
1514 hidnplayr 411
 
2366 hidnplayr 412
        cmp     [NET_DRV_LIST+eax*4], 0
413
        je      .error
2220 hidnplayr 414
 
2366 hidnplayr 415
        mov     [NET_DEFAULT], eax
2220 hidnplayr 416
 
2891 hidnplayr 417
        DEBUGF  1,"NET_set_default: succes\n"
2366 hidnplayr 418
        ret
1514 hidnplayr 419
 
420
  .error:
2366 hidnplayr 421
        or      eax, -1
2891 hidnplayr 422
        DEBUGF  1,"NET_set_default: failed\n"
2366 hidnplayr 423
        ret
1514 hidnplayr 424
 
425
 
426
;-----------------------------------------------------------------
427
;
428
; NET_Remove_Device:
429
;
430
;  This function is called by etwork drivers,
431
;  to unregister network devices from the kernel
2891 hidnplayr 432
;
1514 hidnplayr 433
;  IN:  Pointer to device structure in ebx
434
;  OUT: eax: -1 on error
435
;
436
;-----------------------------------------------------------------
437
align 4
438
NET_remove_device:
439
 
2366 hidnplayr 440
        cmp     [NET_RUNNING], 0
441
        je      .error
1514 hidnplayr 442
 
2366 hidnplayr 443
        cmp     [NET_DRV_LIST], ebx
444
        jne     @f
445
        mov     [NET_DRV_LIST], 0
446
        cmp     [NET_RUNNING], 1
447
        je      @f
448
        ; there are still active devices, find one and make it default
449
        xor     eax, eax
450
        mov     ecx, MAX_NET_DEVICES
451
        mov     edi, NET_DRV_LIST
452
        repe    scasd
453
        je      @f
454
        shr     edi, 2
455
        dec     edi
456
        mov     [NET_DEFAULT], edi
2220 hidnplayr 457
       @@:
458
 
1514 hidnplayr 459
;----------------------------
460
; Find the driver in the list
461
 
2366 hidnplayr 462
        mov     eax, ebx
463
        mov     ecx, MAX_NET_DEVICES
464
        mov     edi, NET_DRV_LIST+4
1514 hidnplayr 465
 
2366 hidnplayr 466
        repne   scasd
467
        jnz     .error
1514 hidnplayr 468
 
469
;------------------------
470
; Remove it from the list
471
 
2366 hidnplayr 472
        xor     eax, eax
473
        mov     dword [edi-4], eax
1514 hidnplayr 474
 
3340 hidnplayr 475
        call    NET_send_event
476
 
2366 hidnplayr 477
        dec     [NET_RUNNING]
478
        ret
1514 hidnplayr 479
 
480
  .error:
2366 hidnplayr 481
        or      eax, -1
482
        ret
1514 hidnplayr 483
 
484
 
485
 
486
;-----------------------------------------------------------------
487
;
488
; NET_ptr_to_num
489
;
490
; IN:  ebx = ptr to device struct
491
; OUT: edi = -1 on error, device number otherwise
492
;
493
;-----------------------------------------------------------------
494
align 4
495
NET_ptr_to_num:
2366 hidnplayr 496
        push    ecx
1514 hidnplayr 497
 
2366 hidnplayr 498
        mov     ecx, MAX_NET_DEVICES
499
        mov     edi, NET_DRV_LIST
1514 hidnplayr 500
 
501
  .loop:
2366 hidnplayr 502
        cmp     ebx, [edi]
503
        jz      .found
504
        add     edi, 4
505
        dec     ecx
506
        jnz     .loop
1514 hidnplayr 507
 
2366 hidnplayr 508
        ; repnz  scasd could work too if eax is used instead of ebx!
1514 hidnplayr 509
 
2366 hidnplayr 510
        or      edi, -1
1514 hidnplayr 511
 
2366 hidnplayr 512
        pop     ecx
513
        ret
1514 hidnplayr 514
 
515
  .found:
2366 hidnplayr 516
        sub     edi, NET_DRV_LIST
517
        shr     edi, 2
1514 hidnplayr 518
 
2366 hidnplayr 519
        pop     ecx
520
        ret
1514 hidnplayr 521
 
522
;-----------------------------------------------------------------
523
;
1249 hidnplayr 524
; checksum_1
525
;
1482 hidnplayr 526
;  This is the first of two functions needed to calculate a checksum.
1249 hidnplayr 527
;
1473 hidnplayr 528
;  IN:  edx = start offset for semi-checksum
1249 hidnplayr 529
;       esi = pointer to data
530
;       ecx = data size
531
;  OUT: edx = semi-checksum
532
;
1473 hidnplayr 533
;
534
; Code was optimized by diamond
535
;
1249 hidnplayr 536
;-----------------------------------------------------------------
537
align 4
538
checksum_1:
1159 hidnplayr 539
 
2366 hidnplayr 540
        shr     ecx, 1
541
        pushf
542
        jz      .no_2
1159 hidnplayr 543
 
2366 hidnplayr 544
        shr     ecx, 1
545
        pushf
546
        jz      .no_4
1473 hidnplayr 547
 
2366 hidnplayr 548
        shr     ecx, 1
549
        pushf
550
        jz      .no_8
1473 hidnplayr 551
 
552
  .loop:
2366 hidnplayr 553
        add     dl, [esi+1]
554
        adc     dh, [esi+0]
1473 hidnplayr 555
 
2366 hidnplayr 556
        adc     dl, [esi+3]
557
        adc     dh, [esi+2]
1473 hidnplayr 558
 
2366 hidnplayr 559
        adc     dl, [esi+5]
560
        adc     dh, [esi+4]
1473 hidnplayr 561
 
2366 hidnplayr 562
        adc     dl, [esi+7]
563
        adc     dh, [esi+6]
1473 hidnplayr 564
 
2366 hidnplayr 565
        adc     edx, 0
566
        add     esi, 8
1473 hidnplayr 567
 
2366 hidnplayr 568
        dec     ecx
569
        jnz     .loop
1473 hidnplayr 570
 
2366 hidnplayr 571
        adc     edx, 0
1473 hidnplayr 572
 
573
  .no_8:
2366 hidnplayr 574
        popf
575
        jnc     .no_4
1473 hidnplayr 576
 
2366 hidnplayr 577
        add     dl, [esi+1]
578
        adc     dh, [esi+0]
1473 hidnplayr 579
 
2366 hidnplayr 580
        adc     dl, [esi+3]
581
        adc     dh, [esi+2]
1473 hidnplayr 582
 
2366 hidnplayr 583
        adc     edx, 0
584
        add     esi, 4
1473 hidnplayr 585
 
586
  .no_4:
2366 hidnplayr 587
        popf
588
        jnc     .no_2
1473 hidnplayr 589
 
2366 hidnplayr 590
        add     dl, [esi+1]
591
        adc     dh, [esi+0]
1473 hidnplayr 592
 
2366 hidnplayr 593
        adc     edx, 0
594
        inc     esi
595
        inc     esi
1473 hidnplayr 596
 
597
  .no_2:
2366 hidnplayr 598
        popf
599
        jnc     .end
1159 hidnplayr 600
 
2366 hidnplayr 601
        add     dh, [esi+0]
602
        adc     edx, 0
1473 hidnplayr 603
  .end:
2366 hidnplayr 604
        ret
1159 hidnplayr 605
 
1249 hidnplayr 606
;-----------------------------------------------------------------
607
;
608
; checksum_2
609
;
610
;  This function calculates the final ip/tcp/udp checksum for you
611
;
612
;  IN:  edx = semi-checksum
613
;  OUT: dx = checksum (in INET byte order)
614
;
615
;-----------------------------------------------------------------
616
align 4
617
checksum_2:
618
 
2366 hidnplayr 619
        mov     ecx, edx
620
        shr     ecx, 16
621
        and     edx, 0xffff
622
        add     edx, ecx
1249 hidnplayr 623
 
2366 hidnplayr 624
        mov     ecx, edx
625
        shr     ecx, 16
626
        add     dx, cx
627
        test    dx, dx          ; it seems that ZF is not set when CF is set :(
628
        not     dx
629
        jnz     .not_zero
630
        dec     dx
1249 hidnplayr 631
  .not_zero:
2366 hidnplayr 632
        xchg    dl, dh
1249 hidnplayr 633
 
3251 hidnplayr 634
        DEBUGF  1,"Checksum: %x\n", dx
1249 hidnplayr 635
 
2366 hidnplayr 636
        ret
1249 hidnplayr 637
 
638
 
639
 
1159 hidnplayr 640
;----------------------------------------------------------------
641
;
3146 hidnplayr 642
;  System function to work with network devices (75)
1159 hidnplayr 643
;
644
;----------------------------------------------------------------
645
align 4
2366 hidnplayr 646
sys_network:                    ; FIXME: make default device easily accessible
1159 hidnplayr 647
 
2366 hidnplayr 648
        cmp     ebx, -1
649
        jne     @f
1196 hidnplayr 650
 
2366 hidnplayr 651
        mov     eax, [NET_RUNNING]
652
        jmp     .return
1196 hidnplayr 653
 
654
   @@:
2366 hidnplayr 655
        cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
656
        jae     .doesnt_exist
1159 hidnplayr 657
 
2366 hidnplayr 658
        mov     esi, ebx
659
        and     esi, 0x0000ff00
660
        shr     esi, 6
1159 hidnplayr 661
 
2366 hidnplayr 662
        cmp     dword [esi + NET_DRV_LIST], 0   ; check if driver is running
663
        je      .doesnt_exist
1159 hidnplayr 664
 
2621 hidnplayr 665
        mov     eax, [esi + NET_DRV_LIST]
2220 hidnplayr 666
 
2621 hidnplayr 667
        and     ebx, 0x000000ff
668
        cmp     ebx, .number
669
        ja      .doesnt_exist
670
        jmp     dword [.table + 4*ebx]
2220 hidnplayr 671
 
2621 hidnplayr 672
  .table:
673
        dd      .get_type               ; 0
674
        dd      .get_dev_name           ; 1
675
        dd      .reset                  ; 2
676
        dd      .stop                   ; 3
677
        dd      .get_ptr                ; 4
678
        dd      .get_drv_name           ; 5
679
        dd      .set_default            ; 6
680
  .number = ($ - .table) / 4 - 1
1514 hidnplayr 681
 
2621 hidnplayr 682
  .get_type:                            ; 0 = Get device type (ethernet/token ring/...)
683
 
684
        mov     eax, [eax + NET_DEVICE.type]
2366 hidnplayr 685
        jmp     .return
1159 hidnplayr 686
 
687
 
2621 hidnplayr 688
  .get_dev_name:                        ; 1 = Get device name
1159 hidnplayr 689
 
2621 hidnplayr 690
        mov     esi, [eax + NET_DEVICE.name]
2366 hidnplayr 691
        mov     edi, ecx
1159 hidnplayr 692
 
2621 hidnplayr 693
        mov     ecx, 64/4 ; max length
694
        rep     movsd
1159 hidnplayr 695
 
2366 hidnplayr 696
        xor     eax, eax
697
        jmp     .return
1159 hidnplayr 698
 
2621 hidnplayr 699
  .reset:                               ; 2 = Reset the device
1159 hidnplayr 700
 
2621 hidnplayr 701
        call    [eax + NET_DEVICE.reset]
2366 hidnplayr 702
        jmp     .return
1192 hidnplayr 703
 
2621 hidnplayr 704
  .stop:                                ; 3 = Stop driver for this device
1192 hidnplayr 705
 
2621 hidnplayr 706
        call    [eax + NET_DEVICE.unload]
2366 hidnplayr 707
        jmp     .return
1192 hidnplayr 708
 
709
 
2621 hidnplayr 710
  .get_ptr:                             ; 4 = Get driver pointer
711
 
2366 hidnplayr 712
        jmp     .return
1249 hidnplayr 713
 
714
 
2621 hidnplayr 715
  .get_drv_name:                        ; 5 = Get driver name
1249 hidnplayr 716
 
2366 hidnplayr 717
        xor     eax, eax
718
        jmp     .return
2220 hidnplayr 719
 
720
 
2621 hidnplayr 721
  .set_default:                         ; 6 = Set default device
2220 hidnplayr 722
 
2366 hidnplayr 723
        call    NET_set_default
724
        jmp     .return
2220 hidnplayr 725
 
1159 hidnplayr 726
  .doesnt_exist:
2366 hidnplayr 727
        mov     eax, -1
1159 hidnplayr 728
 
1192 hidnplayr 729
  .return:
2621 hidnplayr 730
        mov     [esp+32], eax
2366 hidnplayr 731
        ret
1159 hidnplayr 732
 
733
 
734
;----------------------------------------------------------------
735
;
2731 hidnplayr 736
;  System function to work with protocols  (76)
1159 hidnplayr 737
;
738
;----------------------------------------------------------------
739
align 4
740
sys_protocols:
2366 hidnplayr 741
        cmp     bh, MAX_NET_DEVICES             ; Check if device number exists
742
        jae     .doesnt_exist
1159 hidnplayr 743
 
2366 hidnplayr 744
        mov     esi, ebx
745
        and     esi, 0x0000ff00
746
        shr     esi, 6                          ; now we have the device num * 4 in esi
747
        cmp     [esi + NET_DRV_LIST], 0         ; check if driver is running
748
        je      .doesnt_exist
1159 hidnplayr 749
 
2366 hidnplayr 750
        push    .return                         ; return address (we will be using jumps instead of calls)
1159 hidnplayr 751
 
2366 hidnplayr 752
        mov     eax, ebx                        ; set ax to protocol number
753
        shr     eax, 16                         ;
1159 hidnplayr 754
 
2731 hidnplayr 755
        cmp     ax, API_ETH
756
        je      ETH_api
757
 
758
        cmp     ax, API_IPv4
2614 hidnplayr 759
        je      IPv4_api
1159 hidnplayr 760
 
2731 hidnplayr 761
        cmp     ax, API_ICMP
2614 hidnplayr 762
        je      ICMP_api
1159 hidnplayr 763
 
2731 hidnplayr 764
        cmp     ax, API_UDP
2614 hidnplayr 765
        je      UDP_api
1159 hidnplayr 766
 
2731 hidnplayr 767
        cmp     ax, API_TCP
2614 hidnplayr 768
        je      TCP_api
1159 hidnplayr 769
 
2731 hidnplayr 770
        cmp     ax, API_ARP
2614 hidnplayr 771
        je      ARP_api
1159 hidnplayr 772
 
2931 hidnplayr 773
        cmp     ax, API_PPPOE
774
        je      PPPoE_api
2614 hidnplayr 775
 
3185 hidnplayr 776
        cmp     ax, API_IPv6
777
        je      IPv6_api
778
 
2366 hidnplayr 779
        add     esp, 4                           ; if we reached here, no function was called, so we need to balance stack
1159 hidnplayr 780
 
781
  .doesnt_exist:
2366 hidnplayr 782
        mov     eax, -1
1159 hidnplayr 783
 
784
  .return:
2614 hidnplayr 785
        mov     [esp+28+4], eax                 ; return eax value to the program
2366 hidnplayr 786
        ret