From 4005dd5e2c1dccb90a12aa8796cac752b33a2ca2 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Fri, 10 Jul 2015 18:28:57 +0200 Subject: [PATCH] Add simple IPv4 only ifconfig() function from Finit Signed-off-by: Joachim Nilsson --- Makefile | 2 +- README.md | 5 +++ ifconfig.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lite.h | 2 ++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 ifconfig.c diff --git a/Makefile b/Makefile index 6bc5d06..efc817d 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ endif DISTFILES = README LICENSE HEADERS = lite.h OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o fsendfile.o -OBJS += makepath.o pidfile.o pidfilefn.o rsync.o +OBJS += ifconfig.o makepath.o pidfile.o pidfilefn.o rsync.o OBJS += strlcpy.o strlcat.o strtonum.o tempfile.o DEPS := $(OBJS:.o=.d) JUNK = *~ *.bak *.map .*.d *.d DEADJOE semantic.cache *.gdb *.elf core core.* diff --git a/README.md b/README.md index 175a3a1..6835611 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,11 @@ Generic Functions `dst` is allowed to be `NULL` to be able to read and discard `len` bytes from `src`. +- `ifconfig(ifname, addr, mask, up)` + + Basic ifconfig like operations on an interface. Only supports IPv4 + adresses. Note that mask is not CIDR notation. + - `makepath(dir)` Create all components of the specified directory. diff --git a/ifconfig.c b/ifconfig.c new file mode 100644 index 0000000..7a97b23 --- /dev/null +++ b/ifconfig.c @@ -0,0 +1,92 @@ +/* Fastinit (finit) ifconfig() implementation. + * + * Copyright (c) 2008 Claudio Matsuoka + * Copyright (C) 2009-2014 Joachim Nilsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern size_t strlcpy(char *dst, const char *src, size_t siz); + +/** + * ifconfig - Basic ifconfig like operations on an interface + * @ifname: Name of interface to operate on + * @addr: If @up then set this optional IPv4 address + * @mask: If @up and @addr, and @addr is not INADDR_ANY, then set netmask + * @up: Control %IFF_UP flag on interface + * + * Returns: + * POSIX OK(0) on success, or non-zero on error. + */ +int ifconfig(char *ifname, char *addr, char *mask, int up) +{ + int sd, ret = -1; + struct ifreq ifr; + struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; + + if ((sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) + return -1; + + memset(&ifr, 0, sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_addr.sa_family = AF_INET; + + if (up) { + if (addr) { + if (inet_pton(AF_INET, addr, &sin->sin_addr) == 1) + ret = ioctl(sd, SIOCSIFADDR, &ifr); + } + + /* Non-zero IP address */ + if (mask && strcmp(addr, "0.0.0.0")) { + if (inet_pton(AF_INET, mask, &sin->sin_addr) == -1) + ret = ioctl(sd, SIOCSIFNETMASK, &ifr); + } + } + + if (!ioctl(sd, SIOCGIFFLAGS, &ifr)) { + if (up) + ifr.ifr_flags |= IFF_UP; + else + ifr.ifr_flags &= ~IFF_UP; + + ret = ioctl(sd, SIOCSIFFLAGS, &ifr); + } + + close(sd); + + return ret; +} + +/** + * Local Variables: + * version-control: t + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */ diff --git a/lite.h b/lite.h index 8a98542..8541628 100644 --- a/lite.h +++ b/lite.h @@ -45,6 +45,8 @@ int movefile (char *src, char *dst); int fcopyfile (FILE *src, FILE *dst); size_t fsendfile (FILE *src, FILE *dst, size_t len); +int ifconfig (char *ifname, char *addr, char *mask, int up); + int mkpath (char *dir, mode_t mode); int makepath (char *dir);