Last active
March 8, 2017 12:27
-
-
Save VelocityRa/5d5d83446122fd3bedcdf53630a25567 to your computer and use it in GitHub Desktop.
IP Verifier for Networks class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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