MDGSF Software Engineer

[C/C++] Check IP Address valid

2016-04-06
 

1. A,B,C IP Address

(1) Public A,B,C IP Address

A: 0.0.0.0 ~ 127.255.255.255

B: 128.0.0.0 ~ 191.255.255.255

C: 192.0.0.0 ~ 223.255.255.255

(2) Private internal A,B,C IP Address

A: 10.0.0.0 ~ 10.255.255.255

B: 172.16.0.0 ~ 172.31.255.255

C: 192.168.0.0 ~ 192.168.255.255

2. Network ip

IP & Mask ==> 子网号 (不能全为0 或 全为1)

IP & (~Mask) ==> 主机号 (不能全为0 或 全为1)

Example1:

在 192.168.0.0 , 255.255.255.0 的网段中,

网络号是: 192.168.0.0

广播地址是: 192.168.0.255

主机地址是: 192.168.0.1 ~ 192.168.0.254

2^8 - 2 = 256 - 2 = 254 个主机地址。

Example2:

在 192.168.92.70 , 255.255.255.0 的网段中,

网络号是: 192.168.92.0

广播地址是: 192.168.92.255

主机地址是: 192.168.92.1 ~ 192.168.92.254

2^8 - 2 = 256 - 2 = 254 个主机地址。

Example3:

A网段: 192.168.1.2 , 255.255.255.128

B网段: 192.168.1.129 , 255.255.255.128

192.168.1.2 –> 192.168.1.00000010

192.168.1.129 –> 192.168.1.10000001

192.168.1.128 –> 192.168.1.10000000

因为AB的前25位是不一样的,所以AB是不同的网段,即子网号是不一样的。

3. code

checkip.h

#ifndef CHECKIP
#define CHECKIP

enum EIPMSG {
    EVALID,
    EINVALID_IPADDRESS,
    EINVALID_IPMASK,
    EINVALID_NETWORKID,
    EINVALID_HOSTID,
    EINVALID_LOOPBACK_ADDRESS,
    EINVALID_NOT_ABC
};

void g_vIPDeleteZero(char *pc);
bool g_bIPAddressIsValid(const char *pcIPAddress, long long& llIp);
bool g_bIsIPmaskValid(const char *pcIPMask, long long& llMask);
int g_iIpAndMaskIsValid(const char * pcIPAddress, const char * pcIPMask);

bool g_bInTheSameLAN(const char * pcIPAddr1, const char * pcIPMask1,
                                 const char * pcIPAddr2, const char * pcIPMask2);


#endif

checkip.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "checkip.h"

const int MIN_IP_LEN = 7;
const int MAX_IP_LEN = 15;

bool g_bIsValidIPString(const char * pc)
{
    int iLen = strlen(pc);
    if(iLen<MIN_IP_LEN || iLen>MAX_IP_LEN)
    {
        return false;
    }

    bool bCurrentIsDigit = false;
    bool bCurrentIsDot = false;
    int iNum = 0;
    for (int i=0; i<iLen; i++)
    {
        if( isdigit(pc[i]) )
        {
            iNum = iNum*10 + (pc[i]-'0');
            if(iNum > 255)
            {
                return false;
            }
            bCurrentIsDigit = true;
            bCurrentIsDot = false;
        }
        else if( pc[i] == '.' )
        {
            if(!bCurrentIsDigit || bCurrentIsDot)
            {
                return false;
            }
            bCurrentIsDigit = false;
            bCurrentIsDot = true;
            iNum = 0;
        }
        else
        {
            return false;
        }
    }
    if(bCurrentIsDot)
    {
        return false;
    }

    return true;
}

//example:
//Input: 00.007.000.01  Output: 0.7.0.1
void g_vIPDeleteZero(char *pc)
{
    char ac[100] = {0};
    strcpy(ac, pc);
    int iLen = strlen(ac);
    char *pcTemp = &ac[0];
    char *pcFound = NULL;
    int i;
    int j;

    for (i=0; pcTemp[i] != '\0'; i++)
    {
        if(pcTemp[i] == '0')
        {
            if((i+1<3) && isdigit(pcTemp[i+1]))
            {
                pcTemp[i] = 'f';
            }
        }
        else
        {
            pcFound = strchr(pcTemp, '.');
            if(pcFound != NULL)
            {
                pcTemp = pcFound + 1;
                i = -1;
            }
            else
            {
                break;
            }
        }
    }

    for (i=0, j=0; i<iLen; )
    {
        if(ac[i] != 'f')
        {
            pc[j++] = ac[i++];
        }
        else
        {
            i++;
        }
    }
    pc[j] = '\0';
}

void g_vIPchar2Int(const char *pc, long long & ll)
{
    ll = 0;
    char ac[1024] = {0};
    strcpy(ac, pc);

    int iTemp;
    char acTemp[100] = {0};
    char * pcHead = &ac[0];
    char * pcFind = strchr(ac, '.');

    while(pcFind != NULL)
    {
        *pcFind = '\0';
        strcpy(acTemp, pcHead);
        pcFind++;
        pcHead = pcFind;

        iTemp = atoi(acTemp);
        ll = (ll + (long long)iTemp) * 256;

        pcFind = strchr(pcHead, '.');
    }
    strcpy(acTemp, pcHead);
    iTemp = atoi(acTemp);
    ll = ll + (long long)iTemp;
}

bool g_bIPAddressIsValid(const char *pcIPAddress, long long& llIp)
{
    if( !g_bIsValidIPString(pcIPAddress) )
    {
        return false;
    }

    g_vIPchar2Int(pcIPAddress, llIp);

    if((llIp==0) || (llIp==0xffffffff))
    {
        return false;
    }
    else
    {
        return true;
    }
}

bool g_bIsIPmaskValid(const char *pcIPMask, long long& llMask)
{
    if( !g_bIsValidIPString(pcIPMask) )
    {
        return false;
    }

    g_vIPchar2Int(pcIPMask, llMask);

    if((llMask|(llMask-1)) == 0xffffffff)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int g_iIpAndMaskIsValid(const char * pcIPAddress, const char * pcIPMask)
{
    long long llIp = 0;
    long long llMask = 0;

    if(!g_bIPAddressIsValid(pcIPAddress, llIp))
    {
        return EINVALID_IPADDRESS;
    }
    if(!g_bIsIPmaskValid(pcIPMask, llMask))
    {
        return EINVALID_IPMASK;
    }

    int iHead = (llIp & 0xff000000) >> 24;
    if(iHead == 127)
    {
        return EINVALID_LOOPBACK_ADDRESS;
    }
    if( !(iHead>0 && iHead<=223) )
    {
        return EINVALID_NOT_ABC;
    }

    long long llNet = llIp & llMask;
    if(llNet==0 || llNet==llMask)
    {
        return EINVALID_NETWORKID;
    }

    long long llHost = llIp & (~llMask);
    if(llHost==0 || llHost==((~llMask)&0xffffff))
    {
        return EINVALID_HOSTID;
    }
    return EVALID;
}

bool g_bInTheSameLAN(const char * pcIPAddr1, const char * pcIPMask1,
                   const char * pcIPAddr2, const char * pcIPMask2)
{
    long long llIPAddr1 = 0;
    long long llIPMask1 = 0;
    long long llIPAddr2 = 0;
    long long llIPMask2 = 0;

    if( (!g_bIPAddressIsValid(pcIPAddr1, llIPAddr1)) ||
        (!g_bIsIPmaskValid(pcIPMask1, llIPMask1)) ||
        (!g_bIPAddressIsValid(pcIPAddr2, llIPAddr2)) ||
        (!g_bIsIPmaskValid(pcIPMask2, llIPMask2)) )
    {
        return false;
    }

    long long llNet1 = llIPAddr1 & llIPMask1;
    long long llNet2 = llIPAddr2 & llIPMask2;

    return llNet1 == llNet2;
}

weixingongzhonghao

Similar Posts

下一篇 [Qt] checkbox.

Comments