Compare commits
11 commits
58193daba1
...
a8dcb69e1e
Author | SHA1 | Date | |
---|---|---|---|
a8dcb69e1e | |||
9d52478756 | |||
75dbfb7166 | |||
1c2778131f | |||
5ab18f3692 | |||
22f848dd8a | |||
7a5ea4e973 | |||
96c7b39a18 | |||
d6b4cb0f48 | |||
8b94548472 | |||
33de77f32c |
9 changed files with 124 additions and 215 deletions
176
README.md
176
README.md
|
@ -1,71 +1,44 @@
|
||||||
## About
|
## About
|
||||||
|
|
||||||
isinetaddr is a simple C library that provides an interface that can
|
isinetaddr is a clang library that provides a set of functions for
|
||||||
be used to validate an IPv(<b>4</b>|<b>6</b>) address (with optional
|
IP address validation. The library is guided by [testcases](test/)
|
||||||
support for CIDR notation included). The library is guided by easy to
|
that help verify safety and correctness.
|
||||||
extend [testcases](test/) that help verify safety and correctness.
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### IPv4
|
### isinetaddr4
|
||||||
|
|
||||||
The following example demonstrates the `isinetaddr4` function with
|
The `isinetaddr4` function returns `true` when given a valid IPv4 address:
|
||||||
both valid and invalid inputs. The `isinetaddr4` function returns 1
|
|
||||||
when the input given is a valid IPv4 address, and otherwise returns 0.
|
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#include <isinetaddr.h>
|
#include <isinetaddr.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "127.0.0.1", "1.1.1.1", "0.0.0.0" };
|
const char *ipv4[] = {
|
||||||
const char *invalid[] = { "foobar", "0.0.0.0.0", NULL };
|
/* valid */
|
||||||
void validate(const char *str);
|
"127.0.0.1", "1.1.1.1", "0.0.0.0",
|
||||||
|
/* invalid */
|
||||||
|
"0.0.0.0.0", "foobar"
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (isinetaddr4(ipv4[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv4[i]);
|
||||||
}
|
} else {
|
||||||
printf("// invalid\n");
|
printf("%s is an invalid IPv4 address.\n", ipv4[i]);
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (isinetaddr4(str)) {
|
|
||||||
printf("%s is a valid IPv4 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv4 address.\n", str);
|
|
||||||
}
|
}
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Expected output:
|
### iscidraddr4
|
||||||
|
|
||||||
```
|
The `iscidraddr4` function supports the same features as `isinetaddr4` plus
|
||||||
$ cc -Iinclude src/*.c share/isinetaddr/examples/isinetaddr4.c -o example
|
|
||||||
$ ./example
|
|
||||||
// valid
|
|
||||||
127.0.0.1 is a valid IPv4 address.
|
|
||||||
1.1.1.1 is a valid IPv4 address.
|
|
||||||
0.0.0.0 is a valid IPv4 address.
|
|
||||||
// invalid
|
|
||||||
foobar is an invalid IPv4 address.
|
|
||||||
0.0.0.0.0 is an invalid IPv4 address.
|
|
||||||
(null) is an invalid IPv4 address.
|
|
||||||
```
|
|
||||||
|
|
||||||
### CIDR notation (IPv4)
|
|
||||||
|
|
||||||
The `iscidraddr4` function supports the same feature set as `isinetaddr4`, and
|
|
||||||
in addition supports
|
|
||||||
[CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation).
|
[CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation).
|
||||||
The following example builds on the previous example:
|
The following example builds on the previous example:
|
||||||
|
|
||||||
|
@ -74,109 +47,62 @@ The following example builds on the previous example:
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "127.0.0.1", "192.168.2.1/32", "192.168.2.1/0" };
|
const char *ipv4[] = {
|
||||||
const char *invalid[] = { "foobar", "0.0.0.0.0", "192.168.2.1/33" };
|
/* valid */
|
||||||
void validate(const char *str);
|
"127.0.0.1", "192.168.2.1/32", "192.168.2.1/0",
|
||||||
|
/* invalid */
|
||||||
|
"192.168.2.1/33", "foobar"
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (iscidraddr4(ipv4[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv4[i]);
|
||||||
}
|
} else {
|
||||||
printf("// invalid\n");
|
printf("%s is an invalid IPv4 address.\n", ipv4[i]);
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (iscidraddr4(str)) {
|
|
||||||
printf("%s is a valid IPv4 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv4 address.\n", str);
|
|
||||||
}
|
}
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Expected output:
|
### isinetaddr6
|
||||||
|
|
||||||
```
|
The `isinetaddr6` function returns `true` when given a valid IPv6 address:
|
||||||
$ cc -Iinclude src/*.c share/isinetaddr/examples/iscidraddr4.c -o example
|
|
||||||
$ ./example
|
|
||||||
// valid
|
|
||||||
127.0.0.1 is a valid IPv4 address.
|
|
||||||
192.168.2.1/32 is a valid IPv4 address.
|
|
||||||
192.168.2.1/0 is a valid IPv4 address.
|
|
||||||
// invalid
|
|
||||||
foobar is an invalid IPv4 address.
|
|
||||||
0.0.0.0.0 is an invalid IPv4 address.
|
|
||||||
192.168.2.1/33 is an invalid IPv4 address.
|
|
||||||
```
|
|
||||||
|
|
||||||
### IPv6
|
|
||||||
|
|
||||||
The following example demonstrates the `isinetaddr6` function with
|
|
||||||
both valid and invalid inputs. The `isinetaddr6` function returns 1
|
|
||||||
when the input given is a valid IPv6 address, and otherwise returns 0.
|
|
||||||
|
|
||||||
```C
|
```C
|
||||||
#include <isinetaddr.h>
|
#include <isinetaddr.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "::", "::1", "0000:0000:0000:0000:0000:0000:0000:0000" };
|
const char *ipv6[] = {
|
||||||
const char *invalid[] = { "foobar", "00:::0", NULL };
|
/* valid */
|
||||||
void validate(const char *str);
|
"::", "::1", "0000:0000:0000:0000:0000:0000:0000:0000",
|
||||||
|
/* invalid */
|
||||||
|
"foobar", "00:::0"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (isinetaddr6(ipv6[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv6[i]);
|
||||||
|
} else {
|
||||||
|
printf("%s is an invalid IPv4 address.\n", ipv6[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("// invalid\n");
|
return (EXIT_SUCCESS);
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (isinetaddr6(str)) {
|
|
||||||
printf("%s is a valid IPv6 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv6 address.\n", str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Expected output:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cc -Iinclude src/*.c share/isinetaddr/examples/isinetaddr6.c -o example
|
|
||||||
$ ./example
|
|
||||||
// valid
|
|
||||||
:: is a valid IPv6 address.
|
|
||||||
::1 is a valid IPv6 address.
|
|
||||||
0000:0000:0000:0000:0000:0000:0000:0000 is a valid IPv6 address.
|
|
||||||
// invalid
|
|
||||||
foobar is an invalid IPv6 address.
|
|
||||||
00:::0 is an invalid IPv6 address.
|
|
||||||
(null) is an invalid IPv6 address.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Sources
|
## Sources
|
||||||
|
|
||||||
* [Source code (GitHub)](https://github.com/0x1eef/isinetaddr#readme)
|
* [GitHub](https://github.com/0x1eef/isinetaddr#readme)
|
||||||
* [Source code (GitLab)](https://gitlab.com/0x1eef/isinetaddr#about)
|
* [GitLab](https://gitlab.com/0x1eef/isinetaddr#about)
|
||||||
|
|
||||||
## <a id="license"> License </a>
|
## <a id="license"> License </a>
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
v0.3.1
|
v0.3.3
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
int isinetaddr4(const char *str);
|
#include <stdbool.h>
|
||||||
int iscidraddr4(const char *str);
|
bool isinetaddr4(const char *str);
|
||||||
int isinetaddr6(const char *str);
|
bool iscidraddr4(const char *str);
|
||||||
|
bool isinetaddr6(const char *str);
|
||||||
|
|
|
@ -2,30 +2,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "127.0.0.1", "192.168.2.1/32", "192.168.2.1/0" };
|
const char *ipv4[] = {
|
||||||
const char *invalid[] = { "foobar", "0.0.0.0.0", "192.168.2.1/33" };
|
/* valid */
|
||||||
void validate(const char *str);
|
"127.0.0.1", "192.168.2.1/32", "192.168.2.1/0",
|
||||||
|
/* invalid */
|
||||||
|
"192.168.2.1/33", "foobar"
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (iscidraddr4(ipv4[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv4[i]);
|
||||||
}
|
} else {
|
||||||
printf("// invalid\n");
|
printf("%s is an invalid IPv4 address.\n", ipv4[i]);
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (iscidraddr4(str)) {
|
|
||||||
printf("%s is a valid IPv4 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv4 address.\n", str);
|
|
||||||
}
|
}
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "127.0.0.1", "1.1.1.1", "0.0.0.0" };
|
const char *ipv4[] = {
|
||||||
const char *invalid[] = { "foobar", "0.0.0.0.0", NULL };
|
/* valid */
|
||||||
void validate(const char *str);
|
"127.0.0.1", "1.1.1.1", "0.0.0.0",
|
||||||
|
/* invalid */
|
||||||
|
"0.0.0.0.0", "foobar"
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (isinetaddr4(ipv4[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv4[i]);
|
||||||
}
|
} else {
|
||||||
printf("// invalid\n");
|
printf("%s is an invalid IPv4 address.\n", ipv4[i]);
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (isinetaddr4(str)) {
|
|
||||||
printf("%s is a valid IPv4 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv4 address.\n", str);
|
|
||||||
}
|
}
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,23 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *valid[] = { "::", "::1", "0000:0000:0000:0000:0000:0000:0000:0000" };
|
const char *ipv6[] = {
|
||||||
const char *invalid[] = { "foobar", "00:::0", NULL };
|
/* valid */
|
||||||
void validate(const char *str);
|
"::", "::1", "0000:0000:0000:0000:0000:0000:0000:0000",
|
||||||
|
/* invalid */
|
||||||
|
"foobar", "00:::0"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
printf("// valid\n");
|
for (int i = 0; i < 5; i++) {
|
||||||
for (int i = 0; i < 3; i++) {
|
if (isinetaddr6(ipv6[i])) {
|
||||||
validate(valid[i]);
|
printf("%s is a valid IPv4 address.\n", ipv6[i]);
|
||||||
}
|
} else {
|
||||||
printf("// invalid\n");
|
printf("%s is an invalid IPv4 address.\n", ipv6[i]);
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
validate(invalid[i]);
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
validate(const char *str)
|
|
||||||
{
|
|
||||||
if (isinetaddr6(str)) {
|
|
||||||
printf("%s is a valid IPv6 address.\n", str);
|
|
||||||
} else {
|
|
||||||
printf("%s is an invalid IPv6 address.\n", str);
|
|
||||||
}
|
}
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
static int in_range(char buf[4], int min, int max);
|
static bool in_range(char buf[4], int min, int max);
|
||||||
|
|
||||||
int
|
bool
|
||||||
iscidraddr4(const char *str)
|
iscidraddr4(const char *str)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@ -29,14 +30,14 @@ iscidraddr4(const char *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
in_range(char buf[4], int min, int max)
|
in_range(char buf[4], int min, int max)
|
||||||
{
|
{
|
||||||
char *err;
|
char *err;
|
||||||
long r;
|
long r;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (strnlen(buf, 1) == 0) {
|
if (strnlen(buf, 1) == 0) {
|
||||||
return 0;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
r = strtol(buf, &err, 10);
|
r = strtol(buf, &err, 10);
|
||||||
return *err == '\0' && errno == 0 && (r >= min && r <= max);
|
return *err == '\0' && errno == 0 && (r >= min && r <= max);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <isinetaddr.h>
|
#include <isinetaddr.h>
|
||||||
|
|
||||||
static const int MAX_BUFLEN = 3;
|
static const int MAX_BUFLEN = 3;
|
||||||
|
@ -8,44 +9,43 @@ static const int MAX_OCTETS = 4;
|
||||||
static const int MAX_DIGITLEN = 12;
|
static const int MAX_DIGITLEN = 12;
|
||||||
static const int MAX_STRLEN = 16;
|
static const int MAX_STRLEN = 16;
|
||||||
static const char SEP = '.';
|
static const char SEP = '.';
|
||||||
static int within_range(char buf[MAX_BUFLEN]);
|
static bool within_range(char buf[MAX_BUFLEN]);
|
||||||
|
|
||||||
int
|
bool
|
||||||
isinetaddr4(const char *str)
|
isinetaddr4(const char *str)
|
||||||
{
|
{
|
||||||
char buf[MAX_BUFLEN + 1];
|
char buf[MAX_BUFLEN + 1];
|
||||||
int digits = 0, octets = 1, buflen = 0;
|
int digits = 0, octets = 1, buflen = 0;
|
||||||
size_t len = (str == NULL ? 0 : strnlen(str, MAX_STRLEN));
|
size_t len = (str == NULL ? 0 : strnlen(str, MAX_STRLEN));
|
||||||
|
|
||||||
buf[MAX_BUFLEN] = '\0';
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
if (str[i] == SEP) {
|
if (str[i] == SEP) {
|
||||||
if (octets == MAX_OCTETS || buflen == 0) {
|
if (octets == MAX_OCTETS || buflen == 0) {
|
||||||
return 0;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
bzero(buf, MAX_BUFLEN);
|
|
||||||
}
|
}
|
||||||
} else if (isdigit(str[i])) {
|
} else if (isdigit(str[i])) {
|
||||||
if (buflen == MAX_BUFLEN) {
|
if (buflen == MAX_BUFLEN) {
|
||||||
return 0;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
buf[buflen++] = str[i];
|
buf[buflen++] = str[i];
|
||||||
|
buf[buflen] = '\0';
|
||||||
digits++;
|
digits++;
|
||||||
if (!within_range(buf)) {
|
if (!within_range(buf)) {
|
||||||
return 0;
|
return false;
|
||||||
} else if (str[i-1] == SEP) {
|
} else if (i > 0 && str[i-1] == SEP) {
|
||||||
octets++;
|
octets++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return octets == MAX_OCTETS && digits <= MAX_DIGITLEN;
|
return octets == MAX_OCTETS && digits <= MAX_DIGITLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
within_range(char buf[MAX_BUFLEN])
|
within_range(char buf[MAX_BUFLEN])
|
||||||
{
|
{
|
||||||
int n = atoi(buf);
|
int n = atoi(buf);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <isinetaddr.h>
|
#include <isinetaddr.h>
|
||||||
|
|
||||||
static const int MAX_DIGITLEN = 4;
|
static const int MAX_DIGITLEN = 4;
|
||||||
|
@ -9,24 +10,27 @@ static const int MAX_HEXDIGITS = 32;
|
||||||
static const int MAX_STRLEN = 40;
|
static const int MAX_STRLEN = 40;
|
||||||
static const char SEP = ':';
|
static const char SEP = ':';
|
||||||
|
|
||||||
static int has_consecutive_chars(const char *str, char c, int n);
|
static bool has_consecutive_chars(const char *str, char c, int n);
|
||||||
static char* expand(const char *str, size_t strlen, char *new_str, size_t headlen);
|
static char* expand(const char *str, size_t strlen, char *new_str, size_t headlen);
|
||||||
static size_t get_offset(char *tail);
|
static size_t get_offset(char *tail);
|
||||||
|
|
||||||
int
|
bool
|
||||||
isinetaddr6(const char *str)
|
isinetaddr6(const char *str)
|
||||||
{
|
{
|
||||||
int hextets = 1, digitlen = 0, hexdigits = 0;
|
int hextets = 1, digitlen = 0, hexdigits = 0;
|
||||||
size_t len = (str == NULL ? 0 : strnlen(str, MAX_STRLEN));
|
size_t len = (str == NULL ? 0 : strnlen(str, MAX_STRLEN));
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return false;
|
||||||
|
} else if (strncasecmp(str, "::ffff", 6) == 0) {
|
||||||
|
return isinetaddr4(&str[7]);
|
||||||
|
}
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
if (has_consecutive_chars(&str[i], SEP, 3)) {
|
if (has_consecutive_chars(&str[i], SEP, 3)) {
|
||||||
return 0;
|
return false;
|
||||||
} else if (i == 0 && strncasecmp(str, "::ffff", 6) == 0) {
|
|
||||||
return isinetaddr4(&str[7]);
|
|
||||||
} else if (has_consecutive_chars(&str[i], SEP, 2)) {
|
} else if (has_consecutive_chars(&str[i], SEP, 2)) {
|
||||||
if (i == 0 && isinetaddr4(&str[3])) {
|
if (i == 0 && isinetaddr4(&str[3])) {
|
||||||
return 1;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
char new_str[MAX_STRLEN];
|
char new_str[MAX_STRLEN];
|
||||||
return isinetaddr6(expand(str, len, new_str, i));
|
return isinetaddr6(expand(str, len, new_str, i));
|
||||||
|
@ -37,18 +41,18 @@ isinetaddr6(const char *str)
|
||||||
digitlen++;
|
digitlen++;
|
||||||
hexdigits++;
|
hexdigits++;
|
||||||
if (digitlen > MAX_DIGITLEN) {
|
if (digitlen > MAX_DIGITLEN) {
|
||||||
return 0;
|
return false;
|
||||||
} else if (str[i-1] == SEP) {
|
} else if (str[i-1] == SEP) {
|
||||||
hextets++;
|
hextets++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hextets == MAX_HEXTETS && hexdigits <= MAX_HEXDIGITS;
|
return hextets == MAX_HEXTETS && hexdigits <= MAX_HEXDIGITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
has_consecutive_chars(const char *str, char c, int n)
|
has_consecutive_chars(const char *str, char c, int n)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
|
Loading…
Reference in a new issue