Subversion Repositories Kolibri OS

Rev

Rev 485 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 485 Rev 1009
Line 1... Line 1...
1
;
1
;
2
; ETH.INC
2
; ETH.INC
3
;
3
;
4
; made by hidnplayr (hidnplayr@gmail.com) for KolibriOS
4
; made by hidnplayr (hidnplayr@kolibrios.org) for KolibriOS
5
;
5
;
6
; The given code before every macro is only a simple example
6
; The given code before every macro is only a simple example
7
;
7
;
8
;
8
;
9
; HISTORY
9
; HISTORY
10
;
10
;
11
; v1.0: august 2006  original release
11
; v1.0: august 2006  original release
12
; v1.1: december 2006 bugfixes and improvements
12
; v1.1: december 2006 bugfixes and improvements
13
; v1.2: februari 2007 more bugfixes and improvements
13
; v1.2: february 2007 more bugfixes and improvements
Line 14... Line 14...
14
 
14
 
15
macro mov arg1,arg2 {
15
macro mov arg1,arg2 {
16
    if arg1 eq arg2
16
    if arg1 eq arg2
17
    else
17
    else
Line 337... Line 337...
337
   @@:
337
   @@:
Line 338... Line 338...
338
 
338
 
Line 339... Line -...
339
}
-
 
340
 
-
 
341
 
-
 
342
; The function 'resolve' resolves the address in edx and puts the resulting IP in eax.
-
 
343
; When the input is an IP-adress, the function will output this IP in eax.
-
 
344
; If something goes wrong, the result in eax should be 0
-
 
345
;
-
 
346
; example:
-
 
347
;
-
 
348
; resolve query1,IP,PORT
-
 
349
; resolve '192.168.0.1',IP,PORT
-
 
350
; resolve query2,IP,PORT
-
 
351
;
-
 
352
; query1 db 'www.google.com',0
-
 
353
; query2 db '49.78.84.45',0
-
 
354
; IP     dd ?
-
 
355
; PORT   dd ?
-
 
356
 
-
 
357
macro resolve query,result {
-
 
358
 
-
 
359
if    query eqtype 0
-
 
360
 mov   edx,query
-
 
361
else
-
 
362
 local ..string, ..label
-
 
363
 jmp   ..label
-
 
364
 ..string db query,0
-
 
365
 ..label:
-
 
366
 mov   edx,..string
-
 
Line 367... Line -...
367
end   if
-
 
368
 
-
 
369
call  __resolve
-
 
370
 
-
 
371
mov   result,eax
-
 
372
 
-
 
373
}
339
}
374
 
-
 
375
if used __resolve
340
 
376
 
-
 
377
__resolve:
-
 
Line 378... Line 341...
378
 
341
 
Line 379... Line -...
379
if __DEBUG__ eq 1
-
 
380
DEBUGF 1,'DNS: Resolving started\n'
-
 
381
end if
342
 
Line 382... Line 343...
382
 
343
Ip2dword:
383
    ; This code validates if the query is an IP containing 4 numbers and 3 dots
344
    push    edx
384
 
345
 
Line 406... Line 367...
406
    inc     edx 	      ; next byte
367
    inc     edx 	      ; next byte
407
    jmp     @r		      ; lets check for numbers again (jump to previous @@)
368
    jmp     @r		      ; lets check for numbers again (jump to previous @@)
Line 408... Line 369...
408
 
369
 
409
   @@:			      ; we reach this when end of query reached
370
   @@:			      ; we reach this when end of query reached
410
    cmp     al,3	      ; check if there where 3 dots
371
    cmp     al,3	      ; check if there where 3 dots
Line 411... Line 372...
411
    jnz     no_IP	      ; if not, jump to no_IP (this is where the DNS will take over)
372
    jnz     no_IP	      ; if not, jump to no_IP
412
 
373
 
Line 413... Line 374...
413
    ; The following code will convert this IP into a dword and output it in eax
374
    ; The following code will convert this IP into a dword and output it in eax
Line 436... Line 397...
436
.finish:
397
.finish:
437
    shl     edx, 8
398
    shl     edx, 8
438
    add     edx, ebx
399
    add     edx, ebx
Line 439... Line 400...
439
 
400
 
440
    bswap   edx 	      ; we want little endian order
-
 
Line 441... Line 401...
441
    mov     eax, edx
401
    bswap   edx 	      ; we want little endian order
Line 442... Line -...
442
 
-
 
443
    ret
402
 
444
 
-
 
445
 
403
    ret
-
 
404
 
Line 446... Line -...
446
no_IP:
-
 
447
 
-
 
448
    pop     edx
-
 
449
 
-
 
450
    ; The query is not an IP address, we will send the query to a DNS server and hope for answer ;)
-
 
451
if __DEBUG__ eq 1
-
 
452
    DEBUGF 1,'DNS: The query is no ip, Building request string from:%u\n',edx
-
 
453
end if
-
 
454
 
-
 
455
    ; Build the request string
-
 
456
    mov     eax, 0x00010100
-
 
457
    mov     [dnsMsg], eax
-
 
458
    mov     eax, 0x00000100
-
 
459
    mov     [dnsMsg+4], eax
-
 
460
    mov     eax, 0x00000000
-
 
461
    mov     [dnsMsg+8], eax
-
 
462
 
-
 
463
    ; domain name goes in at dnsMsg+12
-
 
464
    mov     esi, dnsMsg + 12			 ; location of label length
-
 
465
    mov     edi, dnsMsg + 13			 ; label start
-
 
466
    mov     ecx, 12				 ; total string length so far
-
 
467
 
-
 
468
td002:
-
 
469
    mov     [esi], byte 0
-
 
470
    inc     ecx
-
 
471
 
-
 
472
td0021:
-
 
473
    mov     al, [edx]
-
 
474
 
-
 
475
    cmp     al, 0
-
 
476
    je	    td001				 ; we have finished the string translation
-
 
477
 
-
 
478
    cmp     al, '.'
-
 
479
    je	    td004				 ; we have finished the label
-
 
480
 
-
 
481
    inc     byte [esi]
-
 
482
    inc     ecx
-
 
483
    mov     [edi], al
-
 
484
    inc     edi
-
 
485
    inc     edx
-
 
486
    jmp     td0021
-
 
487
 
-
 
488
td004:
-
 
489
    mov     esi, edi
-
 
490
    inc     edi
-
 
491
    inc     edx
-
 
492
    jmp     td002
-
 
493
 
-
 
494
    ; write label len + label text
-
 
495
td001:
-
 
496
    mov     [edi], byte 0
-
 
497
    inc     ecx
-
 
498
    inc     edi
-
 
499
    mov     [edi], dword 0x01000100
-
 
500
    add     ecx, 4
-
 
501
 
-
 
502
    mov     [dnsMsgLen], ecx			 ; We'll need the length of the message when we send it
-
 
503
    ; Now, lets send this and wait for an answer
-
 
504
 
-
 
505
    eth.search_port 1024,edx			 ; Find a free port starting from 1025 and store in edx
-
 
506
    eth.get_DNS esi				 ; Read DNS IP from stack into esi
-
 
507
    eth.open_udp edx,53,esi,[socketNum] 	     ; First, open socket
-
 
508
if __DEBUG__ eq 1
-
 
509
    DEBUGF 1,'DNS: Socket opened: %u (port %u)\n',[socketNum],ecx
-
 
510
end if
-
 
511
    eth.write_udp [socketNum],[dnsMsgLen],dnsMsg     ; Write to socket ( request DNS lookup )
-
 
512
if __DEBUG__ eq 1
-
 
513
    DEBUGF 1,'DNS: Data written, length:%u offset:%u\n',[dnsMsgLen],dnsMsg
-
 
514
    DEBUGF 1,'DNS: Waiting for data: (timeout is %us)\n',TIMEOUT
-
 
515
end if
-
 
516
    eth.wait_for_data [socketNum],TIMEOUT,abort  ; Now, we wait for data from remote
-
 
517
    eth.read_data dword[socketNum],dnsMsg,dword[dnsMsgLen],dnsMsg+BUFFER      ; Read the data into the buffer
-
 
518
if __DEBUG__ eq 1
-
 
519
    DEBUGF 1,'Data received, offset:%u buffer size:%u length:%u\n',dnsMsg,BUFFER,esi-dnsMsg
-
 
520
end if
-
 
521
    eth.close_udp [socketNum]			     ; We're done, close the socket
-
 
522
if __DEBUG__ eq 1
-
 
523
    DEBUGF 1,'Closed Socket\n'
-
 
524
end if
-
 
525
 
-
 
526
    ; Now parse the message to get the host IP. Man, this is complicated. It's described in RFC 1035
-
 
527
    ; 1) Validate that we have an answer with > 0 responses
-
 
528
    ; 2) Find the answer record with TYPE 0001 ( host IP )
-
 
529
    ; 3) Finally, copy the IP address to the display
-
 
530
    ; Note: The response is in dnsMsg, the end of the buffer is pointed to by [dnsMsgLen]
-
 
531
 
-
 
532
    mov     esi, dnsMsg
-
 
533
 
-
 
534
    mov     al, [esi+2] 			 ; Is this a response to my question?
-
 
535
    and     al, 0x80
-
 
536
    cmp     al, 0x80
-
 
537
    jne     abort
-
 
538
if __DEBUG__ eq 1
-
 
539
    DEBUGF 1,'DNS: It was a response to my question\n'
-
 
540
end if
-
 
541
 
-
 
542
    mov     al, [esi+3] 			 ; Were there any errors?
-
 
543
    and     al, 0x0F
-
 
544
    cmp     al, 0x00
-
 
545
    jne     abort
-
 
546
 
-
 
547
if __DEBUG__ eq 1
-
 
548
    DEBUGF 1,'DNS: There were no errors\n'
-
 
549
end if
-
 
550
 
-
 
551
    mov     ax, [esi+6] 			 ; Is there ( at least 1 ) answer?
-
 
552
    cmp     ax, 0x00
-
 
553
    je	    abort
-
 
554
 
-
 
555
    ; Header validated. Scan through and get my answer
-
 
556
    add     esi, 12				 ; Skip to the question field
-
 
557
    call    skipName				 ; Skip through the question field
-
 
558
    add     esi, 4				 ; skip past the questions qtype, qclass
-
 
559
 
-
 
560
ctr002z:
-
 
561
    ; Now at the answer. There may be several answers, find the right one ( TYPE = 0x0001 )
-
 
562
    call    skipName
-
 
563
    mov     ax, [esi]
-
 
564
    cmp     ax, 0x0100				 ; Is this the IP address answer?
-
 
565
    jne     ctr002c
-
 
566
    add     esi, 10				 ; Yes! Point eax to the first byte of the IP address
-
 
567
    mov     eax,[esi]
-
 
568
 
-
 
569
    ret
-
 
570
 
-
 
571
 
-
 
572
ctr002c:					 ; Skip through the answer, move to the next
-
 
573
    add     esi, 8
-
 
574
    movzx   eax, byte [esi+1]
-
 
575
    mov     ah, [esi]
-
 
576
    add     esi, eax
-
 
577
    add     esi, 2
-
 
578
 
-
 
579
    cmp     esi, [dnsMsgLen]			 ; Have we reached the end of the msg? This is an error condition, should not happen
-
 
580
    jl	    ctr002z				 ; Check next answer
-
 
581
 
-
 
582
abort:
-
 
583
if __DEBUG__ eq 1
-
 
584
    DEBUGF 1,'DNS: Something went wrong, aborting\n'
-
 
585
end if
-
 
586
    xor     eax,eax
-
 
587
 
-
 
588
    ret
-
 
589
 
-
 
590
 
-
 
591
skipName:
-
 
592
    ; Increment esi to the first byte past the name field
-
 
593
    ; Names may use compressed labels. Normally do.
-
 
594
    ; RFC 1035 page 30 gives details
-
 
595
    mov     al, [esi]
-
 
596
    cmp     al, 0
-
 
597
    je	    sn_exit
-
 
598
    and     al, 0xc0
-
 
599
    cmp     al, 0xc0
-
 
600
    je	    sn001
-
 
601
 
-
 
602
    movzx   eax, byte [esi]
-
 
603
    inc     eax
-
 
604
    add     esi, eax
-
 
605
    jmp     skipName
-
 
606
 
-
 
607
sn001:
-
 
608
    add     esi, 2				 ; A pointer is always at the end
-
 
609
    ret
405
no_IP:
Line 610... Line -...
610
 
-
 
611
sn_exit:
-
 
612
    inc     esi
-
 
613
    ret
-
 
614
 
-
 
615
dnsMsgLen:	dd 0
-
 
616
socketNum:	dd 0xFFFF
-
 
617
 
-
 
618
if ~defined dnsMsg
-