Okay, I reconstructed it...
; nasm -f elf32 -g sockettest.asm -o sockettest.o
; ld -m elf_i386 sockettest.o dns.o -o sockettest
bits 32
global _start
extern resolv
AF_INET equ 2 ; sin_family
SOCK_STREAM equ 1 ; socket type (TCP)
PROTOCOL equ 0 ; just because
SYS_SOCKET equ 1
SYS_CONNECT equ 3
SYS_SEND equ 9
SYS_RECV equ 10
buflen equ 1000
%define htons(x) ((x >> 8) & 0xFF) | ((x & 0xFF) << 8) ; for converting port number to network byte order
; structure for sockaddr_in
struc sockaddr_in
.sin_family: resw 1 ; address family AF_INET 16- bits
.sin_port: resw 1 ; port # 16- bits
.sin_addr: resd 1 ; 32- bit IP address of web server
.sin_pad: resb 8 ; 8 bytes of padding
endstruc
section .data
socket_args dd AF_INET, SOCK_STREAM, 0 ; each arg is given 4 bytes
addr_len dd 1 ; 32- bit IP address
; instance of sockaddr_in structure
sock_addr_inst:
dw AF_INET ; family
dw htons (80) ; network byte order converted HTTP port number
.addr dd 0 ; fill in later- IP address
dd 0, 0 ; 8 bytes of padding
sock_addr_inst_size equ $ - sock_addr_inst
connect_args dd 0, sock_addr_inst, sock_addr_inst_size
name db "www.google.com", 0
msg db"GET / HTTP/1.1", 13, 10
db "Host: www.google.com", 13, 10
db "Connection: close", 13, 10
db "User-Agent: assembly language", 13, 10, 13, 10
msg_len equ $ - msg
section .text
_start:
push name ; "www.google.com"
call resolv ; resolve to www.google.com IP address
add esp, 4 ; clean up stack
cmp eax, -1
je exit
mov [ip_hostname], eax
mov [sock_addr_inst.addr], eax
; set up and create a socket file descriptor
push PROTOCOL
push SOCK_STREAM
push AF_INET
mov ecx, esp ; places socketcall args into ecx for syscall
mov ebx, SYS_SOCKET ; socket function to invoke (1= socket command)
mov eax, 102 ; socketcall syscall
int 0x80
add esp, 12 ; clean up stack
cmp eax, 0 ; test for error (eax= socket file descriptor)
jl exit ; jump if negative (error)
mov [sock_fd], eax ; place the newly created socket file descriptor into sock_fd
mov [connect_args], eax ; this will need the socket fd as an argument also
; now make a connection with the created socket
push dword sock_addr_inst_size ; size of the structure
push dword sock_addr_inst ; address of the structure
push dword [sock_fd] ; identifies the socket
mov ecx, esp ; places connect args into ecx for syscall
mov ebx, SYS_CONNECT ; socket function to invoke (3= socket connect)
mov eax, 102 ; socketcall syscall
int 0x80
add esp, 12 ; clean up stack
cmp eax, 0 ; check for errors
jl exit
; write the request to socket
mov eax, 4
mov ebx, [sock_fd]
mov ecx, msg
mov edx, msg_len
int 80h
; read the page (if they send it to us)
mov eax, 3
mov ebx, [sock_fd]
mov ecx, buffer
mov edx, buflen
int 80h
; write it to stdout
mov edx, eax ; length is whatever we read
mov eax, 4
mov ebx, 1
mov ecx, buffer
int 80h
xor eax, eax ; clear eax if no errors occurred
exit:
mov ebx, eax ; put exit code into ebx
neg ebx
mov eax, 1 ; exit sys call
int 0x80
; this throws away information about what the problem was
; I don't use it
error_exit:
xor ebx, ebx
mov ebx, -1 ; produce -1 exit error code
mov eax, 1 ; exit sys call
int 0x80
section .bss
sock_fd resd 1 ; socket fd = 32- bits
connect_fd resd 1
buffer resb buflen ; address of 1000 byte 'buflen' (1,000 characters at a time)
get_request resb 0x1000 ; 1000 bytes (characters) reserved for the HTTP GET request
cl_name resb 300 ; 300 bytes (characters) reserved for URL typed at command line
cl_path_len resd 1 ; 4 bytes (1 double word) reserved for storing length of typed URL's path
cl_filename_len resd 1 ; 4 bytes to store length of the URL's filename
cl_filename resb 50 ; 50 bytes (characters) reserved for filename to download
cl_hostname resb 50 ; 50 bytes (characters) reserved for the hostname of URL
cl_hostname_len resd 1 ; 4 bytes to store length of the hostname
cl_tail resb 100 ; 100 bytes (characters) reserved for the end of URL (past hostname)
pathname resb 100 ; 100 bytes (characters) for the parsed pathname
ip_hostname resd 1 ; for storing the resolved hostname- to- IP address
So if you can parse the accursed command line properly (good luck!), your socket code should work.
Best,
Frank