Skip to content

Commit

Permalink
Merge pull request #1 from unioslo/ether
Browse files Browse the repository at this point in the history
Make the Ethernet address configurable.
  • Loading branch information
dag-erling authored Mar 26, 2019
2 parents 39e0f89 + fcd6acd commit 1de6ec9
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 8 deletions.
5 changes: 3 additions & 2 deletions include/ft/ethernet.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2016-2017 The University of Oslo
* Copyright (c) 2016-2018 The University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -49,6 +49,7 @@ typedef struct ether_ftr {
uint32_t fcs;
} __attribute__((__packed__)) ether_ftr;

uint32_t ether_crc32(const uint8_t *, size_t);
uint32_t ether_fcs(const uint8_t *, size_t);
const char *ether_parse(const char *, ether_addr *);

#endif
43 changes: 41 additions & 2 deletions lib/libft/ft_ether.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2016 The University of Oslo
* Copyright (c) 2016-2018 The University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -30,6 +30,7 @@
#include <stddef.h>
#include <stdint.h>

#include <ft/ctype.h>
#include <ft/ethernet.h>

static const uint32_t crc32tab[256] = {
Expand Down Expand Up @@ -99,8 +100,11 @@ static const uint32_t crc32tab[256] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};

/*
* Compute the 32-bit Frame Check Sequence for an Ethernet frame.
*/
uint32_t
ether_crc32(const uint8_t *data, size_t len)
ether_fcs(const uint8_t *data, size_t len)
{
uint32_t crc32;

Expand All @@ -109,3 +113,38 @@ ether_crc32(const uint8_t *data, size_t len)
crc32 = (crc32 >> 8) ^ crc32tab[(crc32 ^ *data++) & 0xff];
return (crc32);
}

/*
* Parse the textual representation of an Ethernet address. We accept
* both the traditional colon-separated syntax and the less common
* hyphen-separated syntax.
*/
static const uint8_t x2b[256] = {
['0'] = 0x00, ['1'] = 0x01, ['2'] = 0x02, ['3'] = 0x03,
['4'] = 0x04, ['5'] = 0x05, ['6'] = 0x06, ['7'] = 0x07,
['8'] = 0x08, ['9'] = 0x09, ['A'] = 0x0a, ['B'] = 0x0b,
['C'] = 0x0c, ['D'] = 0x0d, ['E'] = 0x0e, ['F'] = 0x0f,
['a'] = 0x0a, ['b'] = 0x0b, ['c'] = 0x0c, ['d'] = 0x0d,
['e'] = 0x0e, ['f'] = 0x0f,
};
#define is_sep(ch) ((ch) == ':' || (ch) == '-')
const char *
ether_parse(const char *str, ether_addr *addr)
{
const unsigned char *us;
char sep;
int i;

us = (const unsigned char *)str;
if (is_xdigit(us[0]) && is_xdigit(us[1]) && is_sep(us[2])) {
addr->o[0] = x2b[us[0]] << 4 | x2b[us[1]];
sep = us[2];
us += 2;
for (i = 1; i < 6; ++i, us += 3) {
if (us[0] != sep || !is_xdigit(us[1]) || !is_xdigit(us[2]))
return (NULL);
addr->o[i] = x2b[us[1]] << 4 | x2b[us[2]];
}
}
return ((const char *)us);
}
5 changes: 4 additions & 1 deletion sbin/flytrap/flytrap.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd November 14, 2018
.Dd November 21, 2018
.Dt FLYTRAP 8
.Os
.Sh NAME
Expand All @@ -35,6 +35,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl dfnov
.Op Fl e Ar addr
.Op Fl I Ar addr Ns | Ns Ar range Ns | Ns Ar subnet
.Op Fl i Ar addr Ns | Ns Ar range Ns | Ns Ar subnet
.Op Fl p Ar pidfile
Expand All @@ -55,6 +56,8 @@ The following options are available:
.Bl -tag -width Fl
.It Fl d
Enable log messages at debug level or higher.
.It Fl e Ar addr
Use the specified Ethernet address instead of the hardcoded default.
.It Fl f
Foreground mode: do not daemonize and do not create a pidfile.
.It Fl I Ar a.b.c.d Ns | Ns Ar a.b.c.d-e.f.g.h Ns | Ns Ar a.b.c.d/p
Expand Down
22 changes: 20 additions & 2 deletions sbin/flytrap/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ exclude_range(ip4s_node **set, const char *range)
return (0);
}

static int
set_ether_addr(const char *addr)
{
ether_addr ea;
const char *e;

if ((e = ether_parse(addr, &ea)) == NULL || *e != '\0')
return (-1);
ft_verbose("ethernet address %02x:%02x:%02x:%02x:%02x:%02x",
ea.o[0], ea.o[1], ea.o[2], ea.o[3], ea.o[4], ea.o[5]);
flytrap_ether_addr = ea;
return (0);
}

static void
daemonize(void)
{
Expand All @@ -117,7 +131,7 @@ usage(void)
{

fprintf(stderr, "usage: "
"flytrap [-dfnov] [-p pidfile] [-t csvfile] "
"flytrap [-dfnov] [-p pidfile] [-t csvfile] [-e addr] "
"[-Ii addr|range|subnet] [-Xx addr|range|subnet] "
"iface\n");
exit(1);
Expand All @@ -132,7 +146,7 @@ main(int argc, char *argv[])
ifname = NULL;
ft_log_level = FT_LOG_LEVEL_NOTICE;
ft_log_init("flytrap", NULL);
while ((opt = getopt(argc, argv, "dfhI:i:nop:t:vX:x:")) != -1) {
while ((opt = getopt(argc, argv, "de:fhI:i:nop:t:vX:x:")) != -1) {
switch (opt) {
case 'd':
if (ft_log_level > FT_LOG_LEVEL_DEBUG)
Expand All @@ -145,6 +159,10 @@ main(int argc, char *argv[])
if (include_range(&src_set, optarg) != 0)
usage();
break;
case 'e':
if (set_ether_addr(optarg) != 0)
usage();
break;
case 'i':
if (include_range(&dst_set, optarg) != 0)
usage();
Expand Down
1 change: 1 addition & 0 deletions t/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.log
*.trs
/t_ether_addr
/t_ip4_addr
/t_ip4_range
/t_ip4_set
Expand Down
5 changes: 4 additions & 1 deletion t/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
AM_CPPFLAGS = -I$(top_srcdir)/include $(CRYB_TEST_CFLAGS)
LIBFT = $(top_builddir)/lib/libft/libft.a
noinst_HEADERS = t_ip4.h
noinst_HEADERS = t_ether.h t_ip4.h

if HAVE_CRYB_TEST

check_PROGRAMS =

check_PROGRAMS += t_ether_addr
t_ether_addr_LDADD = $(LIBFT) $(CRYB_TEST_LIBS)

check_PROGRAMS += t_ip4_addr
t_ip4_addr_LDADD = $(LIBFT) $(CRYB_TEST_LIBS)

Expand Down
52 changes: 52 additions & 0 deletions t/t_ether.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*-
* Copyright (c) 2016-2018 The University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#ifndef T_ETHER_H_INCLUDED
#define T_ETHER_H_INCLUDED

#include <string.h>

#include <ft/endian.h>
#include <ft/ethernet.h>

static inline int
t_compare_ether_addr(const ether_addr *e, const ether_addr *r)
{

if (memcmp(e, r, sizeof(ether_addr)) != 0) {
t_printv("expected %02x:%02x:%02x:%02x:%02x:%02x\n"
"received %02x:%02x:%02x:%02x:%02x:%02x\n",
e->o[0], e->o[1], e->o[2], e->o[3], e->o[4], e->o[5],
r->o[0], r->o[1], r->o[2], r->o[3], r->o[4], r->o[5]);
return (0);
}
return (1);
}

#endif
Loading

0 comments on commit 1de6ec9

Please sign in to comment.