summaryrefslogtreecommitdiff
path: root/src/local_ip.c
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-11-22 09:33:38 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-11-22 10:42:26 -0800
commitcb55706633bda6c5bd7c8391da9193ad0146002b (patch)
tree236d75d4f3a7a2911f3609eb0f983f1e189f53ea /src/local_ip.c
parentfb1bf8a2eefbdb467a948688ab388628455ef480 (diff)
downloadvyatta-cfg-system-cb55706633bda6c5bd7c8391da9193ad0146002b.tar.gz
vyatta-cfg-system-cb55706633bda6c5bd7c8391da9193ad0146002b.zip
Add utilities checking addresses
These are new C language utilites to replace the Perl utility when checking interface addresses. Perl compilation is major component of slow boot time. Note: this changes the package from pure scripts (arch independent) to arch dependent
Diffstat (limited to 'src/local_ip.c')
-rw-r--r--src/local_ip.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/local_ip.c b/src/local_ip.c
new file mode 100644
index 00000000..3707559f
--- /dev/null
+++ b/src/local_ip.c
@@ -0,0 +1,64 @@
+/*
+ * Test if an IP address is assigned to the local system
+ *
+ * This uses the fact Linux will not allow binding to an address that
+ * is not on the system. It is much faster than scanning all the
+ * interface addresses.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int main(int argc, char **argv)
+{
+ int af, s;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s x.x.x.x\n", argv[0]);
+ return -1;
+ }
+
+ af = strchr(argv[1], ':') ? AF_INET6 : AF_INET;
+ s = socket(af, SOCK_STREAM, 0);
+ if (s < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ if (af == AF_INET) {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ };
+
+ if (inet_pton(af, argv[1], &sin.sin_addr) <= 0) {
+ fprintf(stderr, "%s: invalid address\n", argv[1]);
+ return -1;
+ }
+
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ if (errno == EADDRNOTAVAIL)
+ return 1;
+ perror("bind");
+ return -1;
+ }
+ } else {
+ struct sockaddr_in6 sin6;
+
+ if (inet_pton(af, argv[1], &sin6.sin6_addr) <= 0) {
+ fprintf(stderr, "%s: invalid address\n", argv[1]);
+ return -1;
+ }
+
+ if (bind(s, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
+ if (errno == EADDRNOTAVAIL)
+ return 1;
+ perror("bind");
+ return -1;
+ }
+ }
+ return 0;
+}