having trouble with the Windows socket "bind" function

Started by mkdutchman, January 22, 2008, 10:53:25 PM

Previous topic - Next topic

mkdutchman

The system returns with an error message "The system detected an invalid pointer address in attempting to use a pointer argument in a call."

I'm pretty sure I'm not setting up the socketaddr structure correctly, not so?

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    .486                                ; create 32 bit code
    .model flat, stdcall                ; 32 bit memory model
    option casemap :none                ; case sensitive
 
    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\Comctl32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\oleaut32.inc
    include \masm32\include\msvcrt.inc
    include \masm32\include\wsock32.inc
   
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Comctl32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\oleaut32.lib
    includelib \masm32\lib\msvcrt.lib
    includelib \masm32\lib\wsock32.lib

    .data?
        socketdesc  dd  ?
        memptr      dd  ?
        Msgstring   db  512 DUP (?)
    .data
        socketaddr  db  AF_INET,"192.168.3.1",0
        mFlags      dd  FORMAT_MESSAGE_FROM_SYSTEM
        Source      dd  NULL
        Lng         dd  NULL
        bSize       dd  512
        Arg         dd  NULL
        works       db  "It works!!!",NULL
        Capt        db  "Debug messagebox",NULL

    .code

start:
 
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GlobalAlloc,GPTR,2000
    mov memptr,eax
    cmp eax,NULL
    jz  didnwork

invoke WSAStartup,00000002h,eax
    cmp eax,NULL
    jnz direct
   
invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
    cmp eax,INVALID_SOCKET
    jz  didnwork
    mov socketdesc,eax

invoke bind,socketdesc,addr socketaddr,14
    cmp eax,NULL
    jz worked

invoke WSAGetLastError
    jmp direct


worked:
invoke MessageBox,0,addr works,addr Capt,MB_OK
invoke ExitProcess,NULL
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
didnwork:
invoke  GetLastError
direct:
invoke  FormatMessage,mFlags,Source,eax,Lng,addr Msgstring,bSize,Arg
invoke MessageBox,0,addr Msgstring,addr Capt,MB_OK
invoke ExitProcess,NULL
end start

evlncrn8

socketaddr  db  AF_INET,"192.168.3.1",0

looks VERY wrong to me...

-----------------

int bind (

    SOCKET s,   
    const struct sockaddr FAR*  name,   
    int namelen   
   );   


Parameters

s

[in] A descriptor identifying an unbound socket.

name

[in] The address to assign to the socket. The sockaddr structure is defined as follows:

struct sockaddr {
u_short    sa_family;
char       sa_data[14];
};   


Except for the sa_family field, sockaddr contents are expressed in network byte order.

namelen

[in] The length of the name.

ossama

try this,i have modified your code:

.486                                ; create 32 bit code
    .model flat, stdcall                ; 32 bit memory model
    option casemap :none                ; case sensitive
 
    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\Comctl32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\oleaut32.inc
    include \masm32\include\msvcrt.inc
    include \masm32\include\wsock32.inc
   
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Comctl32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\oleaut32.lib
    includelib \masm32\lib\msvcrt.lib
    includelib \masm32\lib\wsock32.lib

    .data?
        socketdesc  dd  ?
        memptr      dd  ?
        Msgstring   db  512 DUP (?)
    .data
;;;;;        socketaddr  db  AF_INET,"192.168.3.1",0
sz_local_hostname db 1024 dup(0)
socketaddr sockaddr_in<>
        mFlags      dd  FORMAT_MESSAGE_FROM_SYSTEM
        Source      dd  NULL
        Lng         dd  NULL
        bSize       dd  512
        Arg         dd  NULL
        works       db  "It works!!!",NULL
        Capt        db  "Debug messagebox",NULL

    .code

start:
 
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GlobalAlloc,GPTR,2000
    mov memptr,eax
    cmp eax,NULL
    jz  didnwork

invoke WSAStartup,00000002h,eax
    cmp eax,NULL
    jnz direct
   
invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
    cmp eax,INVALID_SOCKET
    jz  didnwork
    mov socketdesc,eax

;set family address
mov socketaddr.sin_family,AF_INET

;set local port
invoke htons,2008 ;this is your choice, i have choose local port = 2008
mov socketaddr.sin_port,ax

;set local address (i deleted the error check handling,this is to you
invoke gethostname,addr sz_local_hostname,sizeof sz_local_hostname
.if eax!=0
;do your error handling
.endif
invoke gethostbyname,addr sz_local_hostname
.if eax==NULL
;;do your error handling
.endif
mov eax,(hostent ptr [eax]).h_list
mov eax,[eax]
mov eax,[eax]
mov socketaddr.sin_addr,eax

;bind
invoke bind,socketdesc,addr socketaddr,addr socketaddr
    cmp eax,NULL
    jz worked

invoke WSAGetLastError
    jmp direct


worked:
invoke MessageBox,0,addr works,addr Capt,MB_OK
invoke ExitProcess,NULL
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
didnwork:
invoke  GetLastError
direct:
invoke  FormatMessage,mFlags,Source,eax,Lng,addr Msgstring,bSize,Arg
invoke MessageBox,0,addr Msgstring,addr Capt,MB_OK
invoke ExitProcess,NULL
end start

mkdutchman

The modified code works great, thanks ossama :U

Now I have another couple questions, I was reading through the MASM documentation and couldn't find this anywhere

socketaddr sockaddr_in<>
What does this do? (Dumb newbie question, I know ::))

mov socketaddr.sin_family,AF_INET
mov socketaddr.sin_port,2008

Does this create elements in an array?

mov eax,(hostent ptr [eax]).h_list
I'm lost on this one, is this (hostent ptr [eax]).h_list a macro?

xmetal

Quote from: mkdutchman on January 23, 2008, 05:37:50 PM
socketaddr sockaddr_in <>
What does this do? (Dumb newbie question, I know ::))

Reserve space in the data section for a variable socketaddr whose type is sockaddr_in. The empty angle brackets indicate initialization with null.

Quote from: mkdutchman on January 23, 2008, 05:37:50 PM
mov socketaddr.sin_family,AF_INET
mov socketaddr.sin_port,2008

Does this create elements in an array?

mov instructions are used to copy values into registers and memory, not "create elements in an array".

Quote from: mkdutchman on January 23, 2008, 05:37:50 PM
mov eax,(hostent ptr [eax]).h_list
I'm lost on this one, is this (hostent ptr [eax]).h_list a macro?

No. its like a typecast. The above code is equivalent to:


assume eax:ptr hostent
mov eax,[eax].h_list


If you do not typecast, you will have to manually specify the offset. Like this:


mov eax,[eax+12]

mkdutchman

I'm trying to get to the bottom of my ignorance here........I think my problem is I'm clueless about the following structure,
sockaddr {
u_short    sa_family;
char       sa_data[14];


What 14 chars of data is supposed to go into the sa_data field?

xmetal

The bottom of your ignorance lies in the source of that structure definition.

The correct definition is:


struct sockaddr
{
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};

mkdutchman

Yes, that does clear things up a bit, thanks

Now the following:

        struct  in_addr sin_addr;
        char    sin_zero[8]

The struct in_addr sin_addr is the IP address, correct? And if so, how is it expressed? As a doubleword? Or as a text string, e.g. 192.168.0.254
And what is the purpose of the eight chars after that?

Tedd

For ip4 it's simply 4 bytes..

"192.168.0.254" would be 0fe00a8c0h, and "127.0.0.1" is 0100007fh

If you use the inet_addr function you can just give it your ip-addr string and it will return the correct value for sin_addr.
No snowflake in an avalanche feels responsible.

mkdutchman