Friday, September 21, 2012

C範例程式 : 判斷 IP 是否在給定的 subnet

為了搭配自己的 shell script 寫了這隻小程式, 沒有做一些多餘的錯誤檢查(因為 shell script 餵過去的資料已經處理過).只支援 IPv4 及一種 subnet 表示法. (只用了 stdio.h stdlib.h string.h )
程式碼
#include 
#include 
#include 

int main(int argc, char **argv)
{
 int uip[4], dst[4], nm[4], i = 0, netmask;
 char *delim = ".";
 char *dstdelim = "/";
 char * pch;
 char * dstip;
 char * mask;
 int j = 128;

 /* Check number of argc */
 if(argc != 3){
  printf("Usage : ipinsubnet UIP DSTIP/NETMASK\n");
  printf("Example : ipinsubnet 192.168.0.1 192.168.0.0/24\n");
  return 1;
 }

 /* For uip */
 i = 0;
 pch = strtok(argv[1], delim);
 while (pch != NULL){
  uip[i] = atoi(pch);
  pch = strtok(NULL, delim);
  i++;
 } 

 /* For dst IP and netmask */
 i = 0;
 /* Get dst IP */
 dstip = strtok(argv[2], dstdelim);

 /* Get netmask */
 mask = strtok(NULL, dstdelim);
 netmask = atoi(mask);

        pch = strtok(dstip, delim);
 while (pch != NULL){
  dst[i] = atoi(pch);
  pch = strtok(NULL, delim);
  i++;
 }

 /* Generate netmask */
 i = 0;
 while((netmask - 8) >= 0){
  nm[i] = 255;
  netmask-=8;
  i++;
 }

 if( netmask > 0 ){
  nm[i] = 0;
  for(; netmask > 0; netmask--){ nm[i] = nm[i] | j; j >>= 1; }
  i++;
 }
 for(;i < 4; i++){ nm[i] = 0; }

 /* Compare uip and dst with netmask */
 for(i = 0; i < 4; i++){
  if( (uip[i] & nm[i]) != (dst[i] & nm[i]) ){ printf("F\n"); return 0; }
 }
 printf("T\n");

 return 0;
}

使用範例
$ ./ipinsubnet
Usage : ipinsubnet UIP DSTIP/NETMASK
Example : ipinsubnet 192.168.0.1 192.168.0.0/24

$ ./ipinsubnet 192.168.68.1 192.168.78.0/16
T
$ ./ipinsubnet 192.168.68.1 192.168.78.0/20
T
$ ./ipinsubnet 192.168.68.1 192.168.78.0/21
F
$ ./ipinsubnet 192.168.68.1 192.168.78.0/22
F

No comments: