added ip[46] scanning routines.
parent
23ad357186
commit
dc60cb52bd
@ -0,0 +1,26 @@
|
|||||||
|
.TH scan_ip4 3
|
||||||
|
.SH NAME
|
||||||
|
scan_ip4 \- parse an IPv4 number in dotted-decimal notation
|
||||||
|
.SH SYNTAX
|
||||||
|
.B #include <ip4.h>
|
||||||
|
|
||||||
|
int \fBscan_ip4\fP(const char *\fIsrc\fR,char \fIip\fR[4]);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
scan_ip4 parses an IPv4 number in dotted-decimal ASCII representation
|
||||||
|
from \fIsrc\fR and writes the result into \fIip\fR. It returns the
|
||||||
|
number of bytes read from \fIsrc\fR or 0 if the parsing failed.
|
||||||
|
|
||||||
|
Unlike many other IP parsing routines, scan_ip4 does not recognize octal
|
||||||
|
(like \fB0177.0.0.1\fR) or hexadecimal numbers (like \fB0x7f000001\fR).
|
||||||
|
.SH EXAMPLE
|
||||||
|
#include <str.h>
|
||||||
|
.br
|
||||||
|
#include <ip4.h>
|
||||||
|
|
||||||
|
char buf[]="160.45.40.10";
|
||||||
|
char ip[4];
|
||||||
|
if (scan_ip4(buf,ip) != str_len(buf))
|
||||||
|
parse_error();
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
fmt_ip4(3), scan_ip6(3)
|
@ -0,0 +1,19 @@
|
|||||||
|
#include "scan.h"
|
||||||
|
#include "ip4.h"
|
||||||
|
|
||||||
|
unsigned int scan_ip4(const char *s,char ip[4])
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
unsigned long u;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
for (i=0; i<4; ++i) {
|
||||||
|
register unsigned int j;
|
||||||
|
len+=(j=scan_ulong(s,&u))+1;
|
||||||
|
if (!j) return 0;
|
||||||
|
ip[i]=u; s+=j;
|
||||||
|
if (*s!='.') return 0; ++s;
|
||||||
|
}
|
||||||
|
return len-1;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
.TH scan_ip6 3
|
||||||
|
.SH NAME
|
||||||
|
scan_ip6 \- parse an IPv6 number in ASCII representation
|
||||||
|
.SH SYNTAX
|
||||||
|
.B #include <ip6.h>
|
||||||
|
|
||||||
|
int \fBscan_ip6\fP(const char *\fIsrc\fR,char \fIip\fR[16]);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
scan_ip6 parses an IPv6 number in RFC1884 ASCII representation
|
||||||
|
from \fIsrc\fR and writes the result into \fIip\fR. It returns the
|
||||||
|
number of bytes read from \fIsrc\fR or 0 if the parsing failed.
|
||||||
|
|
||||||
|
scan_ip6 accepts upper and lower case hex letters, it understands "::"
|
||||||
|
compression and partial IPv4 addresses as in "::FFFF:129.144.52.38".
|
||||||
|
|
||||||
|
To allow transparent usage of IPv4 in IPv6 applications, scan_ip6 also
|
||||||
|
understands IPv4 addresses in dotted-decimal notation and will return
|
||||||
|
an IPv4-mapped IPv6 address (i.e. "127.0.0.1" will be parsed as
|
||||||
|
"::FFFF:127.0.0.1".
|
||||||
|
|
||||||
|
Unlike many other IP parsing routines, scan_ip6 does not recognize octal
|
||||||
|
(like \fB0177.0.0.1\fR) or hexadecimal numbers (like \fB0x7f000001\fR)
|
||||||
|
in the IPv4 part.
|
||||||
|
.SH EXAMPLE
|
||||||
|
#include <str.h>
|
||||||
|
.br
|
||||||
|
#include <ip6.h>
|
||||||
|
|
||||||
|
char buf[]="::1";
|
||||||
|
char ip[16];
|
||||||
|
if (scan_ip6(buf,ip) != str_len(buf))
|
||||||
|
parse_error();
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
fmt_ip6(3), scan_ip4(3)
|
@ -0,0 +1,109 @@
|
|||||||
|
#include "scan.h"
|
||||||
|
#include "ip4.h"
|
||||||
|
#include "ip6.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPv6 addresses are really ugly to parse.
|
||||||
|
* Syntax: (h = hex digit)
|
||||||
|
* 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh
|
||||||
|
* 2. any number of 0000 may be abbreviated as "::", but only once
|
||||||
|
* 3. The last two words may be written as IPv4 address
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int scan_ip6(const char *s,char ip[16])
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int len=0;
|
||||||
|
unsigned long u;
|
||||||
|
|
||||||
|
char suffix[16];
|
||||||
|
int prefixlen=0;
|
||||||
|
int suffixlen=0;
|
||||||
|
|
||||||
|
for (i=0; i<16; i++) ip[i]=0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (*s == ':') {
|
||||||
|
len++;
|
||||||
|
if (s[1] == ':') { /* Found "::", skip to part 2 */
|
||||||
|
s+=2;
|
||||||
|
len++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
i = scan_xlong(s,&u);
|
||||||
|
if (!i) return 0;
|
||||||
|
if (prefixlen==12 && s[i]=='.') {
|
||||||
|
/* the last 4 bytes may be written as IPv4 address */
|
||||||
|
i=ip4_scan(s,ip+12);
|
||||||
|
if (i)
|
||||||
|
return i+len;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ip[prefixlen++] = (u >> 8);
|
||||||
|
ip[prefixlen++] = (u & 255);
|
||||||
|
s += i; len += i;
|
||||||
|
if (prefixlen==16)
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* part 2, after "::" */
|
||||||
|
for (;;) {
|
||||||
|
if (*s == ':') {
|
||||||
|
if (suffixlen==0)
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
len++;
|
||||||
|
} else if (suffixlen!=0)
|
||||||
|
break;
|
||||||
|
i = scan_xlong(s,&u);
|
||||||
|
if (!i) {
|
||||||
|
len--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (suffixlen+prefixlen<=12 && s[i]=='.') {
|
||||||
|
int j=ip4_scan(s,suffix+suffixlen);
|
||||||
|
if (j) {
|
||||||
|
suffixlen+=4;
|
||||||
|
len+=j;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
prefixlen=12-suffixlen; /* make end-of-loop test true */
|
||||||
|
}
|
||||||
|
suffix[suffixlen++] = (u >> 8);
|
||||||
|
suffix[suffixlen++] = (u & 255);
|
||||||
|
s += i; len += i;
|
||||||
|
if (prefixlen+suffixlen==16)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i=0; i<suffixlen; i++)
|
||||||
|
ip[16-suffixlen+i] = suffix[i];
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long int fromhex(unsigned char c) {
|
||||||
|
if (c>='0' && c<='9')
|
||||||
|
return c-'0';
|
||||||
|
else if (c>='A' && c<='F')
|
||||||
|
return c-'A'+10;
|
||||||
|
else if (c>='a' && c<='f')
|
||||||
|
return c-'a'+10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int scan_ip6_flat(const char *s,char ip[16])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<16; i++) {
|
||||||
|
int tmp;
|
||||||
|
tmp=fromhex(*s++);
|
||||||
|
if (tmp<0) return 0;
|
||||||
|
ip[i]=tmp << 4;
|
||||||
|
tmp=fromhex(*s++);
|
||||||
|
if (tmp<0) return 0;
|
||||||
|
ip[i]+=tmp;
|
||||||
|
}
|
||||||
|
return 32;
|
||||||
|
}
|
Loading…
Reference in New Issue