From b531b1d7e532688a632080700b16c72395cd2073 Mon Sep 17 00:00:00 2001 From: Hizenberg Date: Wed, 4 Sep 2024 23:41:59 +0530 Subject: [PATCH] getaddrinfo() complete --- .gitignore | 1 + .vscode/c_cpp_properties.json | 18 ++++++++++ System_Calls/readme.md | 67 +++++++++++++++++++++++++++++++++-- System_Calls/showip.c | 62 ++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json create mode 100644 System_Calls/showip.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..98a9c05 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${default}" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.22621.0", + "intelliSenseMode": "windows-msvc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/System_Calls/readme.md b/System_Calls/readme.md index 0dac68f..ee98ac2 100644 --- a/System_Calls/readme.md +++ b/System_Calls/readme.md @@ -1,9 +1,13 @@ -# System Calls : +# System Calls Below are the system calls that can be used to access network functionality. * **getaddrinfo()** : + * Purpose : + + It helps set up the structs, specifically **struct addrinfo**. It does all the dirty work like DNS and service name lookup and fill up the structs with all the relevant information based on the parameters passed. + * Function prototye ``` @@ -15,4 +19,63 @@ Below are the system calls that can be used to access network functionality. 1. node : - Type : `const char *` \ No newline at end of file + Type : `const char *` + + Value : Domain name or IP in form of string. + + Purpose : To help find the host computer IP address for connection. + + 2. service : + + Type : `const char *` + + Value : Service/Protocol or Port in form of string. + + Purpose : To help specify the port number in the host computer. + + 3. hints : + + Type : `const struct addrinfo *` + + Value : Pointer to *struct addrinfo*. + + Purpose : To guide how it should fetch relevent data and store it to `struct addrinfo **res`. + + 4. res : + + Type : `struct addrinfo **` + + Value : Pointer to linked list of *struct addrinfo \** + + * Return Type : + + Non-zero value in case of error or zero, otherwise. + + **Code Snippet** + + ``` + int status; + struct addrinfo hints; + struct addrinfo *servinfo; // will point to the results + + memset(&hints, 0, sizeof hints); // make sure the struct is + // garbage free + + + hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; // TCP stream sockets + hints.ai_flags = AI_PASSIVE; // fill in my IP(my host) for me + + if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0){ + fprintf(stderr, "getaddrinfo erro: %s\n", gai_strerror(status)); + exit(1); + } + + // servinfo now points to a linked list of 1 or more struct + // addrinfos + + + // ... do everything until you don't need servinfo anymore ... + + freeaddrinfo(servinfo); // free the linked list + ``` diff --git a/System_Calls/showip.c b/System_Calls/showip.c new file mode 100644 index 0000000..d26038d --- /dev/null +++ b/System_Calls/showip.c @@ -0,0 +1,62 @@ +/* +* Printing the linked list of struct addrinfo +*/ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[] ){ + + struct addrinfo hints, *res, *p; + int status; + char ipstr[INET6_ADDRSTRLEN]; + + if( argc != 2 ){ + fprintf(stderr, "usage: showip hostname\n"); + return 1; + } + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // IP version agnostic + hints.ai_socktype = SOCK_STREAM; + + if((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0){ + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); + return 2; + } + + printf("IP address for %s:\n\n", argv[1]); + + for(p = res ; p != NULL ; p = p->ai_next){ + void *addr; + char *ipver; + + // get the pointer to the address itself, + // different fields in IPv4 and IPv6: + if( p->ai_family == AF_INET ){ + // IPv4 + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; + addr = &(ipv4->sin_addr); + ipver = "IPv4"; + } + else{ + // IPv6 + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; + addr = &(ipv6->sin6_addr); + ipver = "IPv6"; + } + + //convert the IP to a string and print it: + inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr); + printf(" %s: %s\n", ipver, ipstr); + } + + freeaddrinfo(res); // free the linked list + + return 0; +}