分析一个基于C语言实现的IP冲突检测工具。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <getopt.h>
#include <arpa/inet.h>
#define dbg(fmt, args...) printf("\033[1m[ %s ] %03d: "fmt"\033[0m\n\r", __FUNCTION__, __LINE__, ##args)
#define IP_STR_LEN (16)
typedef struct _NET_ {
unsigned int ip;
unsigned int mask;
} NET;
static int debug_on = 0;
static void usage(const char *program)
{
if (NULL == program) {
return;
}
printf("usage: %s [OPTION], check the ip1/mask1 and ip2/mask2 has conflict or not.\n"
"\n"
" -h, --help\n print this message\n"
" -d, --debug\n print more message for debug\n"
" -i, --ip1 the first ip to check\n"
" -m, --mask1 the mask of first ip\n"
" -I, --ip2 the second ip to check\n"
" -M, --mask2 the mask of second ip\n",
program);
return;
}
static unsigned int mask_str_to_val(const char *mask)
{
unsigned int a, b, c, d;
if (sscanf(mask, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) {
dbg("invalid mask:%s", mask);
return 0;
}
/*dbg("%u.%u.%u.%u", a, b, c, d);*/
return (a << 24) + (b << 16) + (c << 8) + (d);
}
static unsigned int ip_str_to_val(const char *ip)
{
struct in_addr s;
if (!ip) {
return 0;
}
inet_pton(AF_INET, ip, (void *)&s);
return (unsigned int)ntohl(s.s_addr);
}
static int process_options(int argc, char * argv[], NET *net1, NET *net2)
{
int c = 0;
int option_index = 0;
char ip_str[IP_STR_LEN] = {0};
char mask_str[IP_STR_LEN] = {0};
static const char *short_options = "hi:m:I:M:d";
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"debug", no_argument, 0, 'd'},
{"ip1", no_argument, 0, 'i'},
{"mask1", no_argument, 0, 'm'},
{"ip2", no_argument, 0, 'I'},
{"mask2", no_argument, 0, 'M'},
{0,0,0,0},
};
for (;;) {
c = getopt_long(argc, argv, short_options,
long_options, &option_index);
if (c == EOF) {
break;
}
switch (c) {
case 'h':
usage(argv[0]);
exit(0);
break;
case 'd':
debug_on = 1;
break;
case 'i':
net1->ip = ip_str_to_val(optarg);
break;
case 'm':
net1->mask = mask_str_to_val(optarg);
break;
case 'I':
net2->ip = ip_str_to_val(optarg);
break;
case 'M':
net2->mask = mask_str_to_val(optarg);
break;
default:
dbg("unknown param:%c", c);
break;
}
}
return 0;
}
static int check_conflict(NET *net1, NET *net2)
{
unsigned int net1_min = net1->ip & net1->mask;
unsigned int net1_max = net1_min + (~net1->mask);
if (net1_min > net1_max) {
dbg("net1_min(%u) > net1_max(%u)", net1_min, net1_max);
return 1;
}
unsigned int net2_min = net2->ip & net2->mask;
unsigned int net2_max = net2_min + ((~net2->mask));
if (debug_on) {
dbg("mask1:%u", ~(net1->mask));
dbg("mask2:%u", ~(net2->mask));
dbg("net1_min:%u, net1_max:%u", net1_min, net1_max);
dbg("net2_min:%u, net2_max:%u", net2_min, net2_max);
}
if (net2_min > net2_max) {
dbg("net2_min(%u) > net2_max(%u)", net2_min, net2_max);
return 1;
}
if (net1_max < net2_min || net1_min > net2_max) {
return 0;
} else {
system("touch /tmp/ip_conflict");
return 1;
}
}
int main(int argc, char *argv[])
{
int conflict = 0;
NET net1;
NET net2;
memset(&net1, 0, sizeof(NET));
memset(&net2, 0, sizeof(NET));
if (process_options(argc, argv, &net1, &net2) < 0) {
return -1;
}
if (0 == net1.ip || 0 == net1.mask || 0 == net2.ip || 0 == net2.mask) {
dbg("no valid net(%u/%u)(%u/%u)", net1.ip, net1.mask, net2.ip, net2.mask);
return -1;
}
conflict = check_conflict(&net1, &net2);
if (debug_on) {
dbg("(%u/%u) VS (%u/%u), conflict:%d", net1.ip, net1.mask, net2.ip, net2.mask, conflict);
}
return conflict;
}
标签:ip,max,min,IP,mask,C语言,Linux,net2,net1
From: https://www.cnblogs.com/adam-ma/p/17994769