Skip to content

Instantly share code, notes, and snippets.

@VelocityRa
Last active March 8, 2017 12:27
Show Gist options
  • Save VelocityRa/5d5d83446122fd3bedcdf53630a25567 to your computer and use it in GitHub Desktop.
Save VelocityRa/5d5d83446122fd3bedcdf53630a25567 to your computer and use it in GitHub Desktop.
IP Verifier for Networks class
#include <stdio.h>
#include <stdbool.h>
#define MAX_IP_LEN 15 // Max length is 4*3 + 3, (max of 4 3-digit numbers, plus 3 periods)
typedef unsigned char BYTE;
// Enum for all possible IP classes
typedef enum {
A, B, C, D, E, LOOPBACK
} IP_CLASS;
// Struct that holds a single IP address (4 bytes + its class)
typedef struct {
BYTE addr[4];
IP_CLASS ip_class;
} IP;
// Reads IP from stdin and finds its class
//
// Returns error code
// Negative value for errors, zero for success
int read_ip(IP *input_ip) {
printf("Enter IP > ");
// If > 255 the remainder is assigned
scanf("%d.%d.%d.%d", &input_ip->addr[0], &input_ip->addr[1], &input_ip->addr[2], &input_ip->addr[3]);
const BYTE class_byte = input_ip->addr[0]; // Save a copy for less typing
IP_CLASS ip_class;
if (class_byte < 127) {ip_class = A;}
else if (class_byte == 127) {ip_class = LOOPBACK; return -1;} // 127... is reserved (loopback address)
else if (class_byte < 192) {ip_class = B;}
else if (class_byte < 224) {ip_class = C;}
else if (class_byte < 240) {ip_class = D;}
else if (class_byte < 255) {ip_class = E;}
input_ip->ip_class = ip_class;
return 0;
}
// Returns whether ip1 and ip2 can connect with each other
bool are_connectable(IP *ip1, IP *ip2) {
switch (ip1->ip_class) {
case A: // A class
return ip1->addr[0] == ip2->addr[0];
case B: // B class
return ip1->addr[0] == ip2->addr[0] && ip1->addr[1] == ip2->addr[1];
case C: // C class
return ip1->addr[0] == ip2->addr[0] && ip1->addr[1] == ip2->addr[1] && ip1->addr[2] == ip2->addr[2];
case D: // Multicast
return true;
case E: // Reserved
case LOOPBACK: // Loopback
return false;
}
return true; // Compiler complains otherwise
}
// Formats given IP for printing
char* format_ip(IP *ip, char *st_buffer) {
sprintf(st_buffer, "%d.%d.%d.%d", ip->addr[0], ip->addr[1], ip->addr[2], ip->addr[3]);
return st_buffer;
}
int main() {
IP ip1, ip2;
char ip1_fmt[MAX_IP_LEN], ip2_fmt[MAX_IP_LEN]; // Formatted counterparts
const int ret1 = read_ip(&ip1);
const int ret2 = read_ip(&ip2);
if (ret1 < 0 || ret2 < 0) {
fprintf(stderr, "One of the IPs is invalid (127...)");
return -1;
}
const bool can_connect = are_connectable(&ip1, &ip2); // Get connectability
format_ip(&ip1, ip1_fmt); format_ip(&ip2, ip2_fmt); // Format them for printing
printf("\n%s%s%s%s\n", ip1_fmt, (can_connect ? " is " : " is NOT "), "connectable with ", ip2_fmt);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment