From 31f1434dfe3770ecbdac1bacb8e0fc4a17b3d671 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 19 Sep 2018 15:16:44 +0200 Subject: libxtables: Integrate getethertype.c from xtables core This moves getethertype.c into libxtables so that both extensions and xtables-nft-multi may use the implementations therein. New users are libebt_arp and libebt_vlan which drop their own duplicated implementations of getethertypebyname() for the shared one. This change originated from a covscan report of extensions' implementations not checking fopen() return value which should be implicitly fixed by this as well. Signed-off-by: Phil Sutter Signed-off-by: Florian Westphal --- extensions/libebt_arp.c | 72 +-------------------- extensions/libebt_vlan.c | 72 +-------------------- iptables/Makefile.am | 2 +- iptables/getethertype.c | 161 ---------------------------------------------- libxtables/Makefile.am | 2 +- libxtables/getethertype.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 305 deletions(-) delete mode 100644 iptables/getethertype.c create mode 100644 libxtables/getethertype.c diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c index 45fc8d73..dc8e306a 100644 --- a/extensions/libebt_arp.c +++ b/extensions/libebt_arp.c @@ -209,76 +209,6 @@ static int brarp_get_mac_and_mask(const char *from, unsigned char *to, unsigned return 0; } -static struct ethertypeent *brarp_getethertypeent(FILE *etherf, const char *name) -{ - static struct ethertypeent et_ent; - char *e, *found_name; - char line[1024]; - - while ((e = fgets(line, sizeof(line), etherf))) { - char *endptr, *cp; - - if (*e == '#') - continue; - - cp = strpbrk(e, "#\n"); - if (cp == NULL) - continue; - *cp = '\0'; - found_name = e; - - cp = strpbrk(e, " \t"); - if (cp == NULL) - continue; - - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') - cp++; - e = strpbrk(cp, " \t"); - if (e != NULL) - *e++ = '\0'; - - et_ent.e_ethertype = strtol(cp, &endptr, 16); - if (*endptr != '\0' || - (et_ent.e_ethertype < ETH_ZLEN || et_ent.e_ethertype > 0xFFFF)) - continue; - - if (strcasecmp(found_name, name) == 0) - return (&et_ent); - - if (e != NULL) { - cp = e; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - e = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - if (strcasecmp(e, name) == 0) - return (&et_ent); - e = cp; - } - } - } - - return NULL; -} - -static struct ethertypeent *brarp_getethertypebyname(const char *name) -{ - struct ethertypeent *e; - FILE *etherf; - - etherf = fopen(_PATH_ETHERTYPES, "r"); - - e = brarp_getethertypeent(etherf, name); - fclose(etherf); - return (e); -} - static int brarp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) @@ -334,7 +264,7 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags, if (i < 0 || i >= (0x1 << 16) || *end !='\0') { struct ethertypeent *ent; - ent = brarp_getethertypebyname(argv[optind - 1]); + ent = getethertypebyname(argv[optind - 1]); if (!ent) xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP " "protocol type"); diff --git a/extensions/libebt_vlan.c b/extensions/libebt_vlan.c index 4e2ea0fc..52cc99fa 100644 --- a/extensions/libebt_vlan.c +++ b/extensions/libebt_vlan.c @@ -50,76 +50,6 @@ static void brvlan_print_help(void) "--vlan-encap [!] encap : Encapsulated frame protocol (hexadecimal or name)\n"); } -static struct ethertypeent *vlan_getethertypeent(FILE *etherf, const char *name) -{ - static struct ethertypeent et_ent; - char *e, *found_name; - char line[1024]; - - while ((e = fgets(line, sizeof(line), etherf))) { - char *endptr, *cp; - - if (*e == '#') - continue; - - cp = strpbrk(e, "#\n"); - if (cp == NULL) - continue; - *cp = '\0'; - found_name = e; - - cp = strpbrk(e, " \t"); - if (cp == NULL) - continue; - - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') - cp++; - e = strpbrk(cp, " \t"); - if (e != NULL) - *e++ = '\0'; - - et_ent.e_ethertype = strtol(cp, &endptr, 16); - if (*endptr != '\0' || - (et_ent.e_ethertype < ETH_ZLEN || et_ent.e_ethertype > 0xFFFF)) - continue; // skip invalid etherproto type entry - - if (strcasecmp(found_name, name) == 0) - return (&et_ent); - - if (e != NULL) { - cp = e; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - e = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - if (strcasecmp(e, name) == 0) - return (&et_ent); - e = cp; - } - } - } - - return NULL; -} - -static struct ethertypeent *brvlan_getethertypebyname(const char *name) -{ - struct ethertypeent *e; - FILE *etherf; - - etherf = fopen(_PATH_ETHERTYPES, "r"); - - e = vlan_getethertypeent(etherf, name); - fclose(etherf); - return (e); -} - static int brvlan_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) @@ -156,7 +86,7 @@ brvlan_parse(int c, char **argv, int invert, unsigned int *flags, vlaninfo->invflags |= EBT_VLAN_ENCAP; local.encap = strtoul(optarg, &end, 16); if (*end != '\0') { - ethent = brvlan_getethertypebyname(optarg); + ethent = getethertypebyname(optarg); if (ethent == NULL) xtables_error(PARAMETER_PROBLEM, "Unknown --vlan-encap value ('%s')", optarg); local.encap = ethent->e_ethertype; diff --git a/iptables/Makefile.am b/iptables/Makefile.am index d0218ddc..581dc32b 100644 --- a/iptables/Makefile.am +++ b/iptables/Makefile.am @@ -43,7 +43,7 @@ xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \ nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \ xtables-monitor.c \ xtables-arp-standalone.c xtables-arp.c \ - getethertype.c nft-bridge.c \ + nft-bridge.c \ xtables-eb-standalone.c xtables-eb.c \ xtables-eb-translate.c \ xtables-translate.c diff --git a/iptables/getethertype.c b/iptables/getethertype.c deleted file mode 100644 index 027ef4ad..00000000 --- a/iptables/getethertype.c +++ /dev/null @@ -1,161 +0,0 @@ -/* -* getethertype.c -* -* This file was part of the NYS Library. -* -** The NYS Library is free software; you can redistribute it and/or -** modify it under the terms of the GNU Library General Public License as -** published by the Free Software Foundation; either version 2 of the -** License, or (at your option) any later version. -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/******************************************************************** -* Description: Ethertype name service switch and the ethertypes -* database access functions -* Author: Nick Fedchik -* Checker: Bart De Schuymer -* Origin: uClibc-0.9.16/libc/inet/getproto.c -* Created at: Mon Nov 11 12:20:11 EET 2002 -********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAXALIASES 35 - -static FILE *etherf = NULL; -static char line[BUFSIZ + 1]; -static struct ethertypeent et_ent; -static char *ethertype_aliases[MAXALIASES]; -static int ethertype_stayopen; - -void setethertypeent(int f) -{ - if (etherf == NULL) - etherf = fopen(_PATH_ETHERTYPES, "r"); - else - rewind(etherf); - ethertype_stayopen |= f; -} - -void endethertypeent(void) -{ - if (etherf) { - fclose(etherf); - etherf = NULL; - } - ethertype_stayopen = 0; -} - -struct ethertypeent *getethertypeent(void) -{ - char *e; - char *endptr; - register char *cp, **q; - - if (etherf == NULL - && (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) { - return (NULL); - } - -again: - if ((e = fgets(line, BUFSIZ, etherf)) == NULL) { - return (NULL); - } - if (*e == '#') - goto again; - cp = strpbrk(e, "#\n"); - if (cp == NULL) - goto again; - *cp = '\0'; - et_ent.e_name = e; - cp = strpbrk(e, " \t"); - if (cp == NULL) - goto again; - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') - cp++; - e = strpbrk(cp, " \t"); - if (e != NULL) - *e++ = '\0'; -// Check point - et_ent.e_ethertype = strtol(cp, &endptr, 16); - if (*endptr != '\0' - || (et_ent.e_ethertype < ETH_ZLEN - || et_ent.e_ethertype > 0xFFFF)) - goto again; // Skip invalid etherproto type entry - q = et_ent.e_aliases = ethertype_aliases; - if (e != NULL) { - cp = e; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < ðertype_aliases[MAXALIASES - 1]) - *q++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - } - *q = NULL; - return (&et_ent); -} - - -struct ethertypeent *getethertypebyname(const char *name) -{ - register struct ethertypeent *e; - register char **cp; - - setethertypeent(ethertype_stayopen); - while ((e = getethertypeent()) != NULL) { - if (strcasecmp(e->e_name, name) == 0) - break; - for (cp = e->e_aliases; *cp != 0; cp++) - if (strcasecmp(*cp, name) == 0) - goto found; - } -found: - if (!ethertype_stayopen) - endethertypeent(); - return (e); -} - -struct ethertypeent *getethertypebynumber(int type) -{ - register struct ethertypeent *e; - - setethertypeent(ethertype_stayopen); - while ((e = getethertypeent()) != NULL) - if (e->e_ethertype == type) - break; - if (!ethertype_stayopen) - endethertypeent(); - return (e); -} diff --git a/libxtables/Makefile.am b/libxtables/Makefile.am index 4267cb5f..8ff6b0ca 100644 --- a/libxtables/Makefile.am +++ b/libxtables/Makefile.am @@ -4,7 +4,7 @@ AM_CFLAGS = ${regular_CFLAGS} AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS} lib_LTLIBRARIES = libxtables.la -libxtables_la_SOURCES = xtables.c xtoptions.c +libxtables_la_SOURCES = xtables.c xtoptions.c getethertype.c libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage} libxtables_la_LIBADD = if ENABLE_STATIC diff --git a/libxtables/getethertype.c b/libxtables/getethertype.c new file mode 100644 index 00000000..027ef4ad --- /dev/null +++ b/libxtables/getethertype.c @@ -0,0 +1,161 @@ +/* +* getethertype.c +* +* This file was part of the NYS Library. +* +** The NYS Library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Library General Public License as +** published by the Free Software Foundation; either version 2 of the +** License, or (at your option) any later version. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/******************************************************************** +* Description: Ethertype name service switch and the ethertypes +* database access functions +* Author: Nick Fedchik +* Checker: Bart De Schuymer +* Origin: uClibc-0.9.16/libc/inet/getproto.c +* Created at: Mon Nov 11 12:20:11 EET 2002 +********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXALIASES 35 + +static FILE *etherf = NULL; +static char line[BUFSIZ + 1]; +static struct ethertypeent et_ent; +static char *ethertype_aliases[MAXALIASES]; +static int ethertype_stayopen; + +void setethertypeent(int f) +{ + if (etherf == NULL) + etherf = fopen(_PATH_ETHERTYPES, "r"); + else + rewind(etherf); + ethertype_stayopen |= f; +} + +void endethertypeent(void) +{ + if (etherf) { + fclose(etherf); + etherf = NULL; + } + ethertype_stayopen = 0; +} + +struct ethertypeent *getethertypeent(void) +{ + char *e; + char *endptr; + register char *cp, **q; + + if (etherf == NULL + && (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) { + return (NULL); + } + +again: + if ((e = fgets(line, BUFSIZ, etherf)) == NULL) { + return (NULL); + } + if (*e == '#') + goto again; + cp = strpbrk(e, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + et_ent.e_name = e; + cp = strpbrk(e, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + e = strpbrk(cp, " \t"); + if (e != NULL) + *e++ = '\0'; +// Check point + et_ent.e_ethertype = strtol(cp, &endptr, 16); + if (*endptr != '\0' + || (et_ent.e_ethertype < ETH_ZLEN + || et_ent.e_ethertype > 0xFFFF)) + goto again; // Skip invalid etherproto type entry + q = et_ent.e_aliases = ethertype_aliases; + if (e != NULL) { + cp = e; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < ðertype_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&et_ent); +} + + +struct ethertypeent *getethertypebyname(const char *name) +{ + register struct ethertypeent *e; + register char **cp; + + setethertypeent(ethertype_stayopen); + while ((e = getethertypeent()) != NULL) { + if (strcasecmp(e->e_name, name) == 0) + break; + for (cp = e->e_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + if (!ethertype_stayopen) + endethertypeent(); + return (e); +} + +struct ethertypeent *getethertypebynumber(int type) +{ + register struct ethertypeent *e; + + setethertypeent(ethertype_stayopen); + while ((e = getethertypeent()) != NULL) + if (e->e_ethertype == type) + break; + if (!ethertype_stayopen) + endethertypeent(); + return (e); +} -- cgit v1.2.3