Skip to content

Instantly share code, notes, and snippets.

@pikulet
Created September 22, 2020 12:17
Show Gist options
  • Save pikulet/8057fd6cbed27b2f2caf1a1088510043 to your computer and use it in GitHub Desktop.
Save pikulet/8057fd6cbed27b2f2caf1a1088510043 to your computer and use it in GitHub Desktop.
whatsmyip in c (nwtools)
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define IP_ADDRESS_STRING_LENGTH 15
#define DELIMITERS "\r\n "
#define SERVER_HOSTNAME "nwtools.atwebpages.com"
#define SERVER_FILEPATH "/yourip.php"
#define SERVER_PORT 80
#define STATUS_OK_CODE "200"
#define CONTENT_LENGTH_HEADER "Content-Length"
#define HTML_BODY_TAG "<body>"
void getMyIP (char *result);
int main()
{
char result[IP_ADDRESS_STRING_LENGTH];
getMyIP(result);
printf("My public IP address is %s\n", result);
return 0;
}
void getMyIP (char *result)
{
// Create socket
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1)
{
perror("Error creating socket");
exit(-1);
}
// DNS resolution for hostname
struct hostent *host;
host = gethostbyname(SERVER_HOSTNAME);
if (host == NULL)
{
perror("Error during DNS resolution");
exit(-1);
}
// Connect to server
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
int connectionResult = connect(
clientSocket,
(struct sockaddr *)&server_addr,
sizeof(struct sockaddr));
if (connectionResult == -1)
{
perror("Error connecting to server");
exit(1);
}
// Create HTTP request
char httpRequest[1024];
sprintf(httpRequest, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",
SERVER_FILEPATH, SERVER_HOSTNAME);
// printf("Sending HTTP Request: \n%s", httpRequest);
// Send HTTP Request
int numBytesSent = send(clientSocket,
httpRequest, strlen(httpRequest), 0);
if (numBytesSent != strlen(httpRequest))
{
perror("Unable to send full message");
exit(-1);
}
// Retrieve HTTP Response
char httpReponse[1024];
int numBytesReceived = recv(
clientSocket,
httpReponse,
1024,
0);
httpReponse[numBytesReceived] = '\0';
// Parse HTTP Response
char *token = NULL;
token = strtok(httpReponse, DELIMITERS);
// Check status code
token = strtok(NULL, DELIMITERS);
int statusOK = strncmp(token, STATUS_OK_CODE, strlen(STATUS_OK_CODE));
if (statusOK != 0)
{
printf("Did not receive status OK, please try again\n");
exit(-1);
}
// Check content length
int contentLengthFound = -1;
while (token && contentLengthFound != 0)
{
token = strtok(NULL, DELIMITERS);
contentLengthFound = strncmp(token, CONTENT_LENGTH_HEADER,
strlen(CONTENT_LENGTH_HEADER));
}
token = strtok(NULL, DELIMITERS);
int contentLength = atoi(token);
if (contentLength <= 0)
{
printf("Did not receive any content, please try again\n");
exit(-1);
}
// Parse for <body> opening tag
int bodyTagFound = -1;
while (token && bodyTagFound != 0)
{
token = strtok(NULL, DELIMITERS);
bodyTagFound = strncmp(token, HTML_BODY_TAG, strlen(HTML_BODY_TAG));
}
token = strtok(NULL, DELIMITERS);
for (int i = 0; i < IP_ADDRESS_STRING_LENGTH; i++)
{
result[i] = token[i + 3]; // offset for "IP:"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment