LCF-AT Posted September 14, 2018 Posted September 14, 2018 Hi guys, today I check some of my windows sockets codes and wanted to update & optimze it a little writing some clean code without to be messy to have also a better view on it.Now I came to the hostent struct which returns a pointer to this struct after calling gethostbyname / gethostbyaddr.Now in the MSDN description I can read that this struct is only used once for each call to this function and getting overwritten by another call.Now they say I should copy the struct into other buffer. Quote The returned hostent structure must be copied to an application buffer if additional calls are to be made to the gethostbyaddr or gethostbyname functions on the same thread. Otherwise, the return value will be overwritten by subsequent gethostbyaddr or gethostbyname calls on the same thread. So does it mean I dont need to copy it into extra buffer if I call the function from diffrent created threads?Just if I use same thread = copy to buffer?So normaly I call requests using that functions by new created threads.Just asking.But also if I would copy the struct into buffer that I also need to copy everything in the whole struct too (whole content) which is a little bad. Next question about this struct.The struct is declared like this... hostent STRUCT h_name DWORD ? h_alias DWORD ? h_addr WORD ? h_len WORD ? h_list DWORD ? hostent ENDS ...and now I would like to access the sub contents of each entrys also via another structs but I dont see any more structs into windows.inc file like getting the entry of the array in h_list for example.So in this case I have to use asm commands like.... mov eax, [eax].hostent.h_list mov eax, [eax] mov eax, [eax] ...without any structs anymore.So,is there any structs I can use go on to access the end content / arrays in windows.inc I didnt seen yet or have I to write any custom struct for that? Structure Address Name Type Value Hex Dump 015C91E8 h_name DWORD 015C9208 015C91EC h_alias DWORD 015C91F8 015C91F0 h_addr WORD 0002 015C91F2 h_len WORD 0004 015C91F4 h_list DWORD 015C91FC $ ==> 015C91E8 <h_name> 015C9208 ASCII "google.com" $+4 015C91EC <h_alias> 015C91F8 $+8 015C91F0 <h_addr> 00040002 ASCII "tx " $+C 015C91F4 <h_list> 015C91FC h_list A NULL-terminated list of addresses for the host... $+14 015C91FC 015C9204 <-- One entry $+18 015C9200 00000000 <-- End List One entry $+1C 015C9204 4E16D9AC <-- Addresses are returned in network byte order On the MSDN I found example like this.. remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET); .... printf("Function returned:\n"); printf("\tOfficial name: %s\n", remoteHost->h_name); for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) { printf("\tAlternate name #%d: %s\n", ++i, *pAlias); ...remoteHost = hostent pointer / access h_alias *pAlias (what is * with what value?) / checking if not 0 / pAlias++.Somehow it checks whether something is in the h_alias array and then it does print it.So why is there a * sign?Dont check that example not complete.Also that with ++ too.Just asking again of course. greetz
fearless Posted September 14, 2018 Posted September 14, 2018 Ive not looked at directly, but i imagine h_alias (h_aliases) is a pointer to a sequence of dwords (an array). Last dword entry is null to indicate array end. Each dword in array is a pointer to a null terminated string. So roughly you could do something like the following (havent tested the code btw): LOCAL remoteHost:DWORD ; pointer to hostent structure LOCAL pAlias:DWORD LOCAL pAliasCurrent:DWORD LOCAL pName:DWORD Invoke gethostbyaddr, Addr szAddress, 4, AF_NET mov remoteHost, eax mov ebx, eax ; remote Host is ebx now mov eax, [ebx].hostent.h_name ; get name mov pName, eax ; save name mov eax, [ebx].hostent.h_alias; get pointer to array of pointers (each to a string) mov pAlias, eax ; save alias mov pAliasCurrent, eax ; use temp var instead of messing with pAlias directly mov eax, [eax] ; get first pointer in array .WHILE eax != 0 ; if pointer is NULL then no more strings ; eax contains a pointer to the null terminated string ; print it here maybe? ; increment array to next pointer add pAliasCurrent, SIZEOF DWORD ; pAlias++ mov ebx, pAliasCurrent mov eax, [ebx] ; get next dword pointer, to see if we should continue or not .ENDW 1
LCF-AT Posted September 15, 2018 Author Posted September 15, 2018 Hi fearless, thanks for your answer.Good ok so it seems I need to handle that as you said without any extra struct. One more small question about website names & direct IP addresses.Which function I could use to check whether its a name or IP if I dont know it before? Websitename: 123.456.789.com IP: 123.456.789.4 Just wanna know how to check if its an NUMERICHOST or not before I use some functions with right flags. greetz
fearless Posted September 15, 2018 Posted September 15, 2018 something like this maybe: IsNumericHost PROC USES ESI lpszHostAddress:DWORD LOCAL RetValue:DWORD mov RetValue, TRUE ; set to initially be true mov esi, lpszHostAddress movzx eax, byte ptr [esi] .WHILE al != 0 .IF al == '.' || ( al >= '0' && al <= '9' ) ; dots or numerics ok .ELSE ; must have encountered a character or other symbol mov RetValue, FALSE .BREAK ; fall out of loop .ENDIF inc esi movzx eax, byte ptr [esi] .ENDW ; if we got to end of string and fell out of loop then all is good ; otherwise if we used break to get here then we got a char mov eax, RetValue ret IsNumericHost ENDP 1
LCF-AT Posted September 15, 2018 Author Posted September 15, 2018 Hi again, ok.So what about IPv6 addresses? fe80::cdff:9f34:d69:7323%11 Just checking for any ":" sign or any double "::"?Just asking so maybe I dont need to handle that IPv6 later. greetz
LCF-AT Posted September 18, 2018 Author Posted September 18, 2018 Hi, I checked a little more some other windows socket functions I didnt used yet and found 2 functions called getaddrinfo & getnameinfo which can handle ipv4 and ipv6 and I dont need to use the other functions I used before.I made some tests and they seems to work pretty well so far and I also save to write more codes if I use them and I get the sockaddr_in & SOCKADDR_IN6 filled already into ADDRINFO struct. Now I have a small questions about function just to be sure whether I can use it as I think at the moment and before disabling my old functions code. Q: getaddrinfo.So at the moment I use this function without to set pHints (filled addrinfo to request) paramter = 0 to get what I can all get back.If the function succeed then I get a filled addrinfo struct back with one or more possible entrys (ai_next) I can check.I did checked the function with some domain names / Ipv4 & Ipv6 strings.In case of google for example I get 2 results back.First is a ai_family IPv6 AF_INET6 and the next one ai_family AF_INET for IPv4.Inside of both are the filled SOCKADDR_IN6 and sockaddr_in struct which I now just use with the socket & connect functions.My code looks like this of both functions... invoke socket,ADDRINFO.ai_family[edi],ADDRINFO.ai_socktype[edi],ADDRINFO.ai_protocol[edi] mov s,eax invoke connect,s,ADDRINFO.ai_addr[edi],ADDRINFO.ai_addrlen[edi] ...all working so far and I get response back later with both anyway whether I use IPv4 or IPv6.The only diffrent I see to the functions paramters of socket & connect is that I used before static values for socket function... invoke socket,AF_INET,SOCK_STREAM,NULL ...only to handle IPv4 and SOCK_STREAM & NULL for protocol.If I use the new functions then I dont get anything into the ai_socktype back just zero.In the description of the socket function is nothing to find about a 0 socket type only from 1 SOCK_STREAM till 5 SOCK_SEQPACKET.Now I call it with zero as type and it works so far.I just wanna know in this case whether its fine or should I better set the type to SOCK_STREAM if the ai_socktype it zero?Or should I keep it original / untouched?Just aksing to prevent possible issues later and also because I dont see any info about a type NULL in socket function.I thought it should fail but it didnt and works also with 0 paramter. greetz 1
LCF-AT Posted September 19, 2018 Author Posted September 19, 2018 Hi again, today I checked again some functions to parse URLs and found 3 functions. http://microsoft.public.win32.programmer.networks.narkive.com/k0t7DFyC/is-there-api-for-parsing-http-addresses-in-ipv6-format CoInternetParseUrl(IPv4): 1.2.3.4 CoInternetParseUrl(IPv6): [FEDC InternetCrackUrl(IPv4): 1.2.3.4 InternetCrackUrl(IPv6): FAILED UrlGetPart(IPv4): 1.2.3.4 UrlGetPart(IPv6): [FEDC Normaly I do use a modded InternetCrackUrl function.Not sure whether there is any function or custom code what can handle all URLs / shemes / protocls etc.Now I have just a tiny question about the definations of paramters of some functions.So in my case I dont have them all into windows inc file and need to write them by myself.Now in the case of this UrlGetPart function I did checked the header file of (shlwapi.h) to find the right values for the paramters like URL_PART_HOSTNAME for this function.On internet I found some and see this as definition... typedef enum { URL_PART_NONE = 0, URL_PART_SCHEME = 1, URL_PART_HOSTNAME, URL_PART_USERNAME, URL_PART_PASSWORD, URL_PART_PORT, URL_PART_QUERY, } URL_PART; typedef enum { URLIS_URL, URLIS_OPAQUE, URLIS_NOHISTORY, URLIS_FILEURL, URLIS_APPLIABLE, URLIS_DIRECTORY, URLIS_HASQUERY, } URLIS; ....URL_PART_NONE has value 0 and URL_PART_SCHEME value 1.Clear so far,but why have the others nothing?In the definition below there have all nothing!Why this?Where to know what value they have?Is that any kind of logic what means something like..."If nothing is there after , = start indexing with 0 then 1 then 2 then 3 etc"?Or what is if for example there is something like this.... typedef enum { URL_PART_NONE, URL_PART_SCHEME, URL_PART_HOSTNAME = 100 URL_PART_USERNAME, URL_PART_PASSWORD, URL_PART_PORT, URL_PART_QUERY, } URL_PART; = 0,1,100,101,102,103,104 ?Just wanna know what is right to be sure not to use any wrong values if nothing is declared like in this examples you know. Thank you
deepzero Posted September 19, 2018 Posted September 19, 2018 Is that any kind of logic what means something like..."If nothing is there after , = start indexing with 0 then 1 then 2 then 3 etc"?Or what is if for example there is something like this.... Yes, you have it right. It starts at 0 by default and increases sequentially by one. if you say ... = 100, it continues from 100, just as you said. 1
kao Posted September 19, 2018 Posted September 19, 2018 @deepzero's answer is correct. If you wish to know more, read about C (or C++) enums. For example, here: https://www.geeksforgeeks.org/enumeration-enum-c/ - section "Interesting facts" answers all the enum questions you asked. 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now