#include #include #include #include #define boolean char #define TRUE 1==1 #define FALSE !TRUE #define NONE 0 #define PORTNR 1 #define IPQUAD 2 #define FQDN 3 #define IPV6 4 int isip(char *s); boolean isportnumber(char *s); boolean isipquad(char *s); boolean isipv6(char *s); boolean isfqdn(char *s); boolean isemailaddress(char *s); char sep='#'; int main(int argc, char *argv[]) { int n; char s[128]; if (argc>1) sep=argv[1][0]; printf("Test the IP detecting stuff. # or ^C to abort.\n\n"); while (1) { n=0; printf("\nGive a string: "); scanf("%s",s); if (strcmp(s,"#")==0) exit(0); if (isportnumber(s)) n=printf("%s qualifies as a port number.\n",s); if (isfqdn(s)) n=printf("%s qualifies as an fqdn.\n",s); if (isipquad(s)) n=printf("%s qualifies as an ip quad.\n",s); if (isipv6(s)) n=printf("%s qualifies as an IPV6.\n",s); if (isemailaddress(s)) n=printf("%s qualifies as an e-mail addres.\n",s); if (n==0) printf("%s qualifies as nothing.\n",s); } } /* See if a string qualifies as a parameter for an IP flag */ int isip(char *s) { if (isportnumber(s)) return(PORTNR); if (isipquad(s)) return(IPQUAD); if (isfqdn(s)) return(FQDN); if (isipv6(s)) return(IPV6); return(NONE); } /* See if string qualifies as a port number */ /* an up to five digit decimal number qualifies */ boolean isportnumber(char *s) { int i=0; char c; while ((c=s[i])!=0 && c!=':' && c!=',') { if (!isdigit(c) || i>4) return(FALSE); i++; } return(TRUE); } /* See if a string qualifies as an ip quad */ /* four nummeric values in the range 0-254,0-254,0-254,0-255 separated by dots. The following ranges are reserved for private networks and hence invalid: 192.168.0.1 through and up to 192.168.255.254 10.0.0.1 through andd up to 10.255.255.254 172.16.0.1 through and up to 172.31.255.254 Also the local hosts: 127.0.0.* and 0.0.0.0 are invalid */ boolean isipquad(char *s) { int n1,n2,n3,n4,dots; long unsigned int ipadr; dots=sscanf(s,"%d.%d.%d.%d",&n1,&n2,&n3,&n4); if (dots<4) return (FALSE); /* too few fields */ if (n1<0 || n2<0 || n3<0 || n4<0) return (FALSE); if (n1>254 || n2>254 || n3>254 || n4>255) return (FALSE); ipadr=(((unsigned long)n1)<<24)+(((unsigned long)n2)<<16)+ (((unsigned long)n3)<<8)+(unsigned long)n4; if (ipadr==0) return(FALSE); if (ipadr>=(192L<<24)+(168L<<16)+1L && ipadr<=(192L<<24)+(168L<<16)+(255L<<8)+254L) return(FALSE); if (ipadr>=(10L<<24)+1 && ipadr<=(10L<<24)+(255L<<16)+(255L<<8)+254L) return(FALSE); if (ipadr>=(172L<<24)+(16L<<16)+1L && ipadr<=(172L<<24)+(31L<<16)+(255L<<8)+254L) return(FALSE); if ((ipadr&0XFFFFFF00L)==(127L<<24)) return(FALSE); return (TRUE); } /* See if a string qualifies as an ipv6 address */ /* The separator character (colon in the IP world) is defined in the global variable sep, default also a colon in this test program. Eight hexadecimal values in the range 0-FFFF separated by a SEP char. The string may be encased in square brackets and then the separation character is always a colon. (':') One or more successive zero values may once be represented by two successive separators. F.e. 1234::6789:abcd expands to 1234:0:0:0:0:0:6789:abcd. All zeros is invalid. */ boolean isipv6(char *s) { int i=0,j=0,n1,n2,n3,n4,n5,n6,n7,n8,seps=0,nrseps=0,doubleseppos=0; char c,sp,t[40],tt[40]; boolean encased=FALSE; /* first see if it is encased */ if (s[i]=='[') { encased=TRUE; i++; sp=':'; } else sp=sep; /* first substitute the separator character by a comma, count them and note the position of two successive separators on the fly */ while (s[i] && i0) { if (ampersand) dot=TRUE; if (s[i-1]=='.' || s[i-1]=='@') return(FALSE); } if (!(isalnum(c)||c=='-'||c=='.'||c=='_'||c=='@')) return(FALSE); i++; } if (s[0]=='.' || s[i-1]=='.') return(FALSE); if (s[0]=='@' || s[i-1]=='@') return(FALSE); return (dot && (ampersand==1)); }