BitLab 0.1.0
BitLab: A Browser for the Bitcoin P2P Network and Blockchain
Loading...
Searching...
No Matches
ip.c
Go to the documentation of this file.
1#include "ip.h"
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <arpa/inet.h>
7#include <resolv.h>
8
9#include "utils.h"
10
11void get_local_ip_address(char* ip_addr)
12{
13 FILE* file = popen("hostname -I", "r");
14 if (file == NULL)
15 {
16 strcpy(ip_addr, " ");
17 return;
18 }
19 char buffer[BUFFER_SIZE];
20 if (fgets(buffer, sizeof(buffer), file) == NULL)
21 {
22 strcpy(ip_addr, " ");
23 pclose(file);
24 return;
25 }
26 pclose(file);
27 char* newline = strchr(buffer, '\n');
28 if (newline != NULL)
29 *newline = '\0';
30 strcpy(ip_addr, buffer);
31}
32
33void get_remote_ip_address(char* ip_addr)
34{
35 FILE* file = popen("curl -s ifconfig.me", "r");
36 if (file == NULL)
37 {
38 strcpy(ip_addr, " ");
39 return;
40 }
41 char buffer[BUFFER_SIZE];
42 if (fgets(buffer, sizeof(buffer), file) == NULL)
43 {
44 strcpy(ip_addr, " ");
45 pclose(file);
46 return;
47 }
48 pclose(file);
49 char* newline = strchr(buffer, '\n');
50 if (newline != NULL)
51 *newline = '\0';
52 strcpy(ip_addr, buffer);
53}
54
55int lookup_address(const char* lookup_addr, char* ip_addr)
56{
57 struct addrinfo hints, * res, * p;
58 int status;
59 char ipstr[INET6_ADDRSTRLEN];
60
61 memset(ip_addr, 0, MAX_IP_ADDR_LEN);
62 memset(&hints, 0, sizeof(hints));
63 hints.ai_family = AF_INET;
64 hints.ai_socktype = SOCK_STREAM;
65
66 if ((status = getaddrinfo(lookup_addr, NULL, &hints, &res)) != 0)
67 {
68 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
69 ip_addr[0] = '\0';
70 return -1;
71 }
72
73 for (p = res; p != NULL; p = p->ai_next)
74 {
75 void* addr = NULL;
76 if (p->ai_family == AF_INET)
77 {
78 struct sockaddr_in* ipv4 = (struct sockaddr_in*)p->ai_addr;
79 addr = &(ipv4->sin_addr);
80 if (addr != NULL)
81 {
82 if (strcmp(inet_ntoa(ipv4->sin_addr), "0.0.0.0") == 0)
83 log_message(LOG_WARN, BITLAB_LOG, __FILE__, "Failed to resolve %s. Appending 0.0.0.0", lookup_addr);
84 inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr));
85 strcat(ip_addr, ipstr);
86 strcat(ip_addr, " ");
87 }
88 }
89 }
90
91 if (strlen(ip_addr) > 0)
92 ip_addr[strlen(ip_addr) - 1] = '\0';
93
94 freeaddrinfo(res);
95 return 0;
96}
97
98int is_in_private_network(const char* ip_addr)
99{
100 if (!is_numeric_address(ip_addr))
101 {
102 char ip[BUFFER_SIZE];
103 log_message(LOG_WARN, BITLAB_LOG, __FILE__, "IP address is not numeric, performing lookup of %s whether it is in private prefix", ip_addr);
104 lookup_address(ip_addr, ip);
105 return is_in_private_network(ip);
106 }
107 unsigned int b1, b2, b3, b4;
108 if (ip_addr == NULL)
109 return 0;
110 if (sscanf(ip_addr, "%u.%u.%u.%u", &b1, &b2, &b3, &b4) != 4)
111 return 0;
112 if ((b1 == 192 && b2 == 168) ||
113 (b1 == 10) ||
114 (b1 == 172 && b2 >= 16 && b2 <= 31))
115 return 1;
116 return 0;
117}
118
119int is_numeric_address(const char* ip_addr)
120{
121 if (ip_addr == NULL)
122 return 0;
123 int dots = 0;
124 for (size_t i = 0; i < strlen(ip_addr); ++i)
125 {
126 if (ip_addr[i] == '.')
127 dots++;
128 else if (ip_addr[i] < '0' || ip_addr[i] > '9')
129 return 0;
130 if (dots > 3)
131 return 0;
132 }
133 return 1;
134}
135
136int is_valid_domain_address(const char* domain_addr)
137{
138 if (domain_addr == NULL)
139 return 0;
140 if (is_numeric_address(domain_addr))
141 return 0;
142 if (strstr(domain_addr, ".") == NULL)
143 return 0;
144 char ip[BUFFER_SIZE];
145 lookup_address(domain_addr, ip);
146 if (strlen(ip) == 0)
147 log_message(LOG_WARN, BITLAB_LOG, __FILE__, "Although %s is a valid domain, it does not resolve", domain_addr);
148 return 1;
149}
void get_local_ip_address(char *ip_addr)
Get the local IP address of the machine (e.g.
Definition ip.c:11
int lookup_address(const char *lookup_addr, char *ip_addr)
Perform lookup of given IP address by the domain address (e.g.
Definition ip.c:55
int is_numeric_address(const char *ip_addr)
Check if the IP address is a numeric address (e.g.
Definition ip.c:119
int is_in_private_network(const char *ip_addr)
Check if the IP address is in the private prefix (e.g.
Definition ip.c:98
int is_valid_domain_address(const char *domain_addr)
Check if the IP address is a valid domain address (e.g.
Definition ip.c:136
void get_remote_ip_address(char *ip_addr)
Get the remote IP address of the machine (e.g.
Definition ip.c:33
void freeaddrinfo(struct addrinfo *res)
const char * gai_strerror(int errcode)
int getaddrinfo(const char *restrict node, const char *restrict service, const struct addrinfo *restrict hints, struct addrinfo **restrict res)
#define MAX_IP_ADDR_LEN
Definition ip.h:8
void log_message(log_level level, const char *filename, const char *source_file, const char *format,...)
Log a message used to log a message to the console or a file.
Definition log.c:89
#define BITLAB_LOG
Definition log.h:11
@ LOG_WARN
Definition log.h:31
Definition ip.h:61
struct sockaddr * ai_addr
Definition ip.h:67
int ai_socktype
Definition ip.h:64
struct addrinfo * ai_next
Definition ip.h:69
int ai_family
Definition ip.h:63
FILE * popen(const char *command, const char *type)
#define BUFFER_SIZE
Definition utils.h:12
int pclose(FILE *stream)