commit 7c02f425c54e3b6548b1ea835cf1455817d55d90 Author: 0x1eef <0x1eef@protonmail.com> Date: Fri Aug 25 15:57:09 2023 -0300 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c78abfa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test/runner diff --git a/.projectile b/.projectile new file mode 100644 index 0000000..e69de29 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..548a1d0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2023 by 0x1eef <0x1eef@protonmail.com> + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f9cd082 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +SRCDIR = src +INCDIR = include +TESTDIR = test +TESTBIN = $(TESTDIR)/runner + +CC = cc +CFLAGS = -I$(INCDIR) -Wall -Wextra -pedantic + +test: + $(CC) $(CFLAGS) $(SRCDIR)/isinetaddr.c $(TESTDIR)/isinetaddr_test.c -o $(TESTBIN) + $(TESTBIN) + +.PHONY: test diff --git a/README.md b/README.md new file mode 100644 index 0000000..79f4da7 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +## About + +isinetaddr is a simple C library that provides an interface that can +be used to validate one or more IPv4 addresses. + +## Examples + +### IPv4 + +The following example demonstrates the `isinetaddr` function with +both valid and invalid inputs. The `isinetaddr` function returns 1 +when the input given is valid, and otherwise returns 0. + +```C +#include +#include +#include + +const char *strings[] = { + "127.0.0.1", "1.1.1.1", "0.0.0.0", + "foobar", "0.0.0.0.0" +}; + +int +main(void) +{ + const char *str; + const int i = sizeof(strings) / sizeof(strings[0]); + for (int j = 0; j < i; j++) { + str = strings[j]; + if(isinetaddr(str)) { + printf("%s is a valid IPv4 address\n", str); + } else { + printf("%s is an invalid IPv4 address\n", str); + } + } + return EXIT_SUCCESS; +} +``` + +When the above source code is compiled and run the output is +expected to be as follows: + +``` +$ cc -Iinclude src/isinetaddr.c share/isinetaddr/examples/IPv4.c -o example +$ ./example +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 +foobar is an invalid IPv4 address +0.0.0.0.0 is an invalid IPv4 address +``` + +## Sources + +* [Source code (GitHub)](https://github.com/0x1eef/isinetaddr#readme) +* [Source code (GitLab)](https://gitlab.com/0x1eef/isinetaddr#about) + +## License + +[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/). +
+See [LICENSE](./LICENSE). diff --git a/include/isinetaddr.h b/include/isinetaddr.h new file mode 100644 index 0000000..df9db54 --- /dev/null +++ b/include/isinetaddr.h @@ -0,0 +1,2 @@ +#pragma once +int isinetaddr(const char *str); diff --git a/share/isinetaddr/examples/IPv4.c b/share/isinetaddr/examples/IPv4.c new file mode 100644 index 0000000..f3d51a4 --- /dev/null +++ b/share/isinetaddr/examples/IPv4.c @@ -0,0 +1,24 @@ +#include +#include +#include + +const char *strings[] = { + "127.0.0.1", "1.1.1.1", "0.0.0.0", + "foobar", "0.0.0.0.0" +}; + +int +main(void) +{ + const char *str; + const int i = sizeof(strings) / sizeof(strings[0]); + for (int j = 0; j < i; j++) { + str = strings[j]; + if(isinetaddr(str)) { + printf("%s is a valid IPv4 address\n", str); + } else { + printf("%s is an invalid IPv4 address\n", str); + } + } + return EXIT_SUCCESS; +} diff --git a/src/isinetaddr.c b/src/isinetaddr.c new file mode 100644 index 0000000..4de8483 --- /dev/null +++ b/src/isinetaddr.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +int +isinetaddr(const char *str) +{ + char buf[4]; + const char *err; + int i = 0, j = 0, k = 0; + + for(int l = 0; l < (int)strnlen(str, 16); l++) { + if (str[l] == '.') { + strtonum(buf, 0, 255, &err); + if (err != NULL) { + return 0; + } else { + k = 0; + j++; + bzero(buf, 3); + buf[3] = '\0'; + } + } else if (isdigit(str[l])) { + buf[k++] = str[l]; + buf[k] = '\0'; + i++; + } else { + return 0; + } + } + return j == 3 && i <= 12 ? 1 : 0; +} diff --git a/test/isinetaddr_test.c b/test/isinetaddr_test.c new file mode 100644 index 0000000..e0589bb --- /dev/null +++ b/test/isinetaddr_test.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +int +main(void) { + /* Assertions */ + assert(isinetaddr("192.168.1.1") == 1); + assert(isinetaddr("0.0.0.0") == 1); + assert(isinetaddr("255.255.255.255") == 1); + assert(isinetaddr("123.45.67.89") == 1); + assert(isinetaddr("192.168.500.1") == 0); + assert(isinetaddr(".192.168.1.1") == 0); + assert(isinetaddr("192..168.1.1") == 0); + assert(isinetaddr("192.168.1.1.") == 0); + assert(isinetaddr("192.168.1.1..") == 0); + assert(isinetaddr("192.168.1.1a") == 0); + assert(isinetaddr("") == 0); + /* Record success */ + printf("OK\n"); + return EXIT_SUCCESS; +}