├── debian ├── compat ├── orig-tar.exclude ├── libfaifa-dev.install ├── libfaifa0.install ├── faifa.install ├── watch ├── changelog ├── README.source ├── orig-tar.sh ├── control └── rules ├── autogen.sh ├── .gitignore ├── aclocal.m4 ├── endian.h ├── configure.ac ├── frame.h ├── device.h ├── sha2.h ├── crc32.h ├── faifa_priv.h ├── crypto.h ├── Makefile.in ├── faifa_compat.h ├── copyright ├── faifa.h.8 ├── crypto.c ├── homeplug.h ├── faifa.h ├── faifa.8 ├── main.c ├── install-sh ├── simulator.c ├── faifa.c ├── hpav_cfg.c ├── sha2.c ├── COPYING └── homeplug_av.h /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/orig-tar.exclude: -------------------------------------------------------------------------------- 1 | debian* 2 | -------------------------------------------------------------------------------- /debian/libfaifa-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/faifa/* 2 | -------------------------------------------------------------------------------- /debian/libfaifa0.install: -------------------------------------------------------------------------------- 1 | usr/lib/libfaifa*.so.* 2 | -------------------------------------------------------------------------------- /debian/faifa.install: -------------------------------------------------------------------------------- 1 | usr/sbin/* 2 | usr/share/man/man8/* 3 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | autoheader 3 | autoconf 4 | rm -rf autom4te.cache 5 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | # There is no Faifa release, yet 2 | # Future releases may be downloaded from https://dev.open-plc.org/ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /config.h* 2 | /config.status 3 | /config.log 4 | /faifa 5 | /hpav_cfg 6 | /*.o 7 | /*.so* 8 | /*.a 9 | /*.la 10 | /Makefile 11 | /configure 12 | /faifa.8.gz 13 | /simulator 14 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | faifa (0.2~svn37-1) unstable; urgency=low 2 | 3 | [ Florian Fainelli ] 4 | * Initial release 5 | 6 | [ Damien Raude-Morvan ] 7 | * Update Debian packaging 8 | 9 | -- Damien Raude-Morvan Fri, 21 Aug 2009 01:00:59 +0200 10 | -------------------------------------------------------------------------------- /debian/README.source: -------------------------------------------------------------------------------- 1 | This package uses quilt to manage all modifications to the upstream 2 | source. Changes are stored in the source package as diffs in 3 | debian/patches and applied during the build. 4 | 5 | See /usr/share/doc/quilt/README.source for a detailed explanation. 6 | -------------------------------------------------------------------------------- /debian/orig-tar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # $1 version 4 | TAR=../faifa_$1.orig.tar.gz 5 | DIR=faifa-$1.orig 6 | REVISION=`echo $1 | sed -e 's/.*svn//'` 7 | BASESVN=trunk 8 | 9 | # clean up the upstream tarball 10 | svn export -r $REVISION https://svn.open-plc.org/$BASESVN $DIR 11 | # Rework Makefile (remove distclean debian handling) 12 | patch -d $DIR -p0 < debian/patches/Makefile.patch 13 | GZIP=--best tar -c -z -f $TAR -X debian/orig-tar.exclude $DIR 14 | rm -rf $DIR 15 | 16 | # move to directory 'tarballs' 17 | if [ -r .svn/deb-layout ]; then 18 | . .svn/deb-layout 19 | mv $TAR $origDir 20 | echo "moved $TAR to $origDir" 21 | fi 22 | 23 | exit 0 24 | 25 | -------------------------------------------------------------------------------- /aclocal.m4: -------------------------------------------------------------------------------- 1 | dnl -------------------------------------------------------------------------- 2 | dnl PA_ADD_CFLAGS() 3 | dnl 4 | dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation 5 | dnl -------------------------------------------------------------------------- 6 | AC_DEFUN(PA_ADD_CFLAGS, 7 | [AC_MSG_CHECKING([if $CC accepts $1]) 8 | pa_add_cflags__old_cflags="$CFLAGS" 9 | CFLAGS="$CFLAGS $1" 10 | AC_TRY_LINK([#include ], 11 | [printf("Hello, World!\n");], 12 | AC_MSG_RESULT([yes]), 13 | AC_MSG_RESULT([no]) 14 | CFLAGS="$pa_add_cflags__old_cflags")]) 15 | 16 | dnl ------------------------------------------------------------------------ 17 | dnl PA_WITH_BOOL 18 | dnl 19 | dnl PA_WITH_BOOL(option, default, help, enable, disable) 20 | dnl 21 | dnl Provides a more convenient way to specify --with-option and 22 | dnl --without-option, with a default. default should be either 0 or 1. 23 | dnl ------------------------------------------------------------------------ 24 | AC_DEFUN(PA_WITH_BOOL, 25 | [AC_ARG_WITH([$1], [$3], 26 | if test ["$withval"] != no; then 27 | [$4] 28 | else 29 | [$5] 30 | fi, 31 | if test [$2] -ne 0; then 32 | [$4] 33 | else 34 | [$5] 35 | fi)]) 36 | -------------------------------------------------------------------------------- /endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __endian_compat_h 2 | #define __endian_compat_h 3 | 4 | #if defined(__linux__) || defined(__GNU__) 5 | #include 6 | #include_next 7 | #elif defined(__APPLE__) 8 | #include 9 | #include 10 | #define bswap_16(x) NXSwapShort(x) 11 | #define bswap_32(x) NXSwapInt(x) 12 | #define bswap_64(x) NXSwapLongLong(x) 13 | #elif defined(__FreeBSD__) 14 | #include 15 | #define bswap_16(x) bswap16(x) 16 | #define bswap_32(x) bswap32(x) 17 | #define bswap_64(x) bswap64(x) 18 | #else 19 | #include 20 | #define bswap_16(x) swap16(x) 21 | #define bswap_32(x) swap32(x) 22 | #define bswap_64(x) swap64(x) 23 | #endif 24 | 25 | #ifndef __BYTE_ORDER 26 | #define __BYTE_ORDER BYTE_ORDER 27 | #endif 28 | #ifndef __BIG_ENDIAN 29 | #define __BIG_ENDIAN BIG_ENDIAN 30 | #endif 31 | #ifndef __LITTLE_ENDIAN 32 | #define __LITTLE_ENDIAN LITTLE_ENDIAN 33 | #endif 34 | 35 | #if __BYTE_ORDER == __BIG_ENDIAN 36 | #define STORE32_LE(X) bswap_32(X) 37 | #elif __BYTE_ORDER == __LITTLE_ENDIAN 38 | #define STORE32_LE(X) (X) 39 | #else 40 | #error unkown endianness! 41 | #endif 42 | 43 | #if __BYTE_ORDER == __BIG_ENDIAN 44 | #define STORE16_LE(X) bswap_16(X) 45 | #elif __BYTE_ORDER == __LITTLE_ENDIAN 46 | #define STORE16_LE(X) (X) 47 | #else 48 | #error unkown endianness! 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT(faifa, 0.2) 2 | AC_PREREQ(2.59) 3 | 4 | AC_PROG_CC 5 | AC_PROG_RANLIB 6 | AC_PROG_INSTALL 7 | 8 | PA_ADD_CFLAGS(-Wall) 9 | 10 | # Basic headers 11 | AC_CHECK_HEADERS(stdio.h) 12 | AC_CHECK_HEADERS(stdlib.h) 13 | AC_CHECK_HEADERS(unistd.h) 14 | AC_CHECK_HEADERS(sys/types.h) 15 | AC_CHECK_HEADERS(arpa/inet.h) 16 | AC_CHECK_HEADERS(errno.h) 17 | AC_CHECK_HEADERS(stdarg.h) 18 | AC_CHECK_HEADERS(string.h) 19 | AC_CHECK_HEADERS(net/if.h) 20 | 21 | # Libraries provided headers 22 | AC_CHECK_HEADERS([pthread.h],,[AC_MSG_ERROR([You need libpthread development files])]) 23 | AC_CHECK_HEADERS([pcap.h],,[AC_MSG_ERROR([You need libpcap development files])]) 24 | 25 | # Check libraries 26 | AC_CHECK_LIB(pthread, pthread_create, 27 | [AC_CHECK_LIB(pthread, pthread_join,[LIBS="${LIBS} -lpthread"], 28 | AC_MSG_ERROR(You need pthread_join check your libpthread))], 29 | AC_MSG_ERROR(You need pthread_create check your libpthread)) 30 | AC_CHECK_LIB(pcap, pcap_lookupdev, 31 | [AC_CHECK_LIB(pcap, pcap_datalink, 32 | [AC_CHECK_LIB(pcap, pcap_next_ex, 33 | [AC_CHECK_LIB(pcap, pcap_sendpacket, 34 | [AC_CHECK_LIB(pcap, pcap_close, 35 | ,AC_MSG_ERROR(You need pcap_close check your libpcap))], 36 | AC_MSG_ERROR(You need pcap_sendpacket check your libpcap))], 37 | AC_MSG_ERROR(You need pcap_next_ex check your libpcap))], 38 | AC_MSG_ERROR(You need pcap_datalink check your libpcap))], 39 | AC_MSG_ERROR(You need pcap_lookupdev check your libpcap)) 40 | 41 | AC_CHECK_HEADERS([event.h],,[AC_MSG_ERROR([You need libevent development files])]) 42 | AC_CHECK_HEADERS([event2/util.h],,[AC_MSG_ERROR([You need libevent development files])]) 43 | 44 | AC_CONFIG_HEADER(config.h) 45 | AC_OUTPUT(Makefile) 46 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: faifa 2 | Section: net 3 | Priority: extra 4 | Maintainer: Florian Fainelli 5 | Uploaders: Damien Raude-Morvan 6 | Build-Depends: debhelper (>= 7), libpcap0.8-dev, quilt 7 | Standards-Version: 3.8.3 8 | Vcs-Svn: http://svn.drazzib.com/debian-pkg/faifa/trunk/ 9 | Vcs-Browser: http://svn.drazzib.com/wsvn/debian-pkg/faifa/trunk/ 10 | Homepage: https://dev.open-plc.org/ 11 | 12 | Package: faifa 13 | Depends: ${shlibs:Depends}, ${misc:Depends} 14 | Architecture: any 15 | Description: Homeplug 1.0/AV tool 16 | Faifa is a network tool to configure, inspect 17 | flash, collect statistics on HomePlug 1.0/AV 18 | devices. 19 | . 20 | It sends all private and public ethernet management 21 | frames to the devices. 22 | . 23 | This package contains faifa tool. 24 | 25 | Package: libfaifa-dev 26 | Section: libdevel 27 | Architecture: any 28 | Depends: libfaifa0 (= ${binary:Version}) 29 | Description: Homeplug 1.0/AV development libraries 30 | Faifa is a network tool to configure, inspect 31 | flash, collect statistics on HomePlug 1.0/AV 32 | devices. 33 | . 34 | It sends all private and public ethernet management 35 | frames to the devices. 36 | . 37 | This package contains faifa development libraries. 38 | 39 | Package: libfaifa0 40 | Section: libs 41 | Architecture: any 42 | Depends: ${shlibs:Depends}, ${misc:Depends} 43 | Description: Homeplug 1.0/AV library 44 | Faifa is a network tool to configure, inspect 45 | flash, collect statistics on HomePlug 1.0/AV 46 | devices. 47 | . 48 | It sends all private and public ethernet management 49 | frames to the devices. 50 | . 51 | This package contains faifa library. 52 | 53 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/quilt/quilt.make 4 | 5 | # Directory for tmp installation of the package. Files must be installed/copied there 6 | # before being packaged 7 | TMPDIR=debian/tmp 8 | 9 | DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ') 10 | UPSTREAM_VERSION := $(shell echo $(DEB_VERSION) | sed 's/-[^-]*$$//') 11 | REVISION := $(shell echo $(UPSTREAM_VERSION) | sed -e 's/.*svn//') 12 | 13 | CFLAGS = -Wall -g 14 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) 15 | CFLAGS += -O0 16 | else 17 | CFLAGS += -O2 18 | endif 19 | 20 | build: build-stamp 21 | build-stamp: $(QUILT_STAMPFN) 22 | dh_testdir 23 | SVN_REV=$(REVISION) $(MAKE) 24 | touch $@ 25 | 26 | clean: unpatch 27 | dh_testdir 28 | dh_testroot 29 | dh_clean build-stamp 30 | $(MAKE) distclean 31 | dh_clean 32 | 33 | install: build 34 | dh_testdir 35 | dh_testroot 36 | dh_prep 37 | dh_installdirs 38 | $(MAKE) DESTDIR=$(CURDIR)/$(TMPDIR) install 39 | 40 | # Build architecture-independent files here. 41 | binary-indep: build install 42 | # We have nothing to do by default. 43 | 44 | # Build architecture-dependent files here. 45 | binary-arch: build install 46 | dh_testdir -a 47 | dh_testroot -a 48 | dh_install -a 49 | dh_installchangelogs -a 50 | dh_installman -a 51 | dh_installdocs -a 52 | dh_link -a 53 | dh_strip -a 54 | dh_compress -a 55 | dh_fixperms -a 56 | dh_makeshlibs -a 57 | dh_shlibdeps -Llibfaifa -l$(CURDIR)/$(TMPDIR)/usr/lib/faifa -a 58 | dh_installdeb -a 59 | dh_gencontrol -a 60 | dh_md5sums -a 61 | dh_builddeb -a 62 | 63 | binary: binary-indep binary-arch 64 | .PHONY: build clean binary-indep binary-arch binary install 65 | 66 | get-orig-source: 67 | sh debian/orig-tar.sh $(UPSTREAM_VERSION) 68 | -------------------------------------------------------------------------------- /frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Frame operations public interface 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | int ether_init_header(void *buf, int len, u_int8_t *da, u_int8_t *sa, u_int16_t ethertype); 53 | int set_init_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, void *user)); 54 | int set_dump_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, struct ether_header *hdr)); 55 | void do_receive_frame(faifa_t *faifa, void *buf, int len, void *UNUSED(user)); 56 | -------------------------------------------------------------------------------- /device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Homeplug 1.0/AV device definitions 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __HPAV_DEVICE_H__ 53 | #define __HPAV_DEVICE_H__ 54 | 55 | #include 56 | #include "homeplug_av.h" 57 | 58 | extern int dump_hex(void *buf, int len, char *sep); 59 | 60 | /** 61 | * hpav_device - structure which contains useful device informations 62 | * @name: name of the device 63 | * @macaddr: MAC address of the device 64 | * @role: role of the device in the HomePlug AV network 65 | * @sw_version: version of the software running on it 66 | * @next: pointer to a hpav_device structure 67 | */ 68 | struct hpav_device { 69 | char *name; /* Device name, if any */ 70 | u_int8_t macaddr[6]; /* MAC address of the device */ 71 | enum sta_role role; /* Device role in the network */ 72 | char *sw_version; /* Software version of the device */ 73 | struct hpav_device *next; 74 | }; 75 | 76 | #endif /* __HPAV_DEVICE_H__ */ 77 | -------------------------------------------------------------------------------- /sha2.h: -------------------------------------------------------------------------------- 1 | /* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.h,v 1.4 2006/07/13 04:15:25 neilc Exp $ */ 2 | /* $OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $ */ 3 | 4 | /* 5 | * FILE: sha2.h 6 | * AUTHOR: Aaron D. Gifford 7 | * 8 | * Copyright (c) 2000-2001, Aaron D. Gifford 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the copyright holder nor the names of contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | * 35 | * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ 36 | */ 37 | 38 | #ifndef _SHA2_H 39 | #define _SHA2_H 40 | 41 | #include 42 | #include 43 | 44 | /* avoid conflict with OpenSSL */ 45 | #define SHA256_Init pg_SHA256_Init 46 | #define SHA256_Update pg_SHA256_Update 47 | #define SHA256_Final pg_SHA256_Final 48 | #define SHA384_Init pg_SHA384_Init 49 | #define SHA384_Update pg_SHA384_Update 50 | #define SHA384_Final pg_SHA384_Final 51 | #define SHA512_Init pg_SHA512_Init 52 | #define SHA512_Update pg_SHA512_Update 53 | #define SHA512_Final pg_SHA512_Final 54 | 55 | /*** SHA-224/256/384/512 Various Length Definitions ***********************/ 56 | #define SHA224_BLOCK_LENGTH 64 57 | #define SHA224_DIGEST_LENGTH 28 58 | #define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) 59 | #define SHA256_BLOCK_LENGTH 64 60 | #define SHA256_DIGEST_LENGTH 32 61 | #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) 62 | #define SHA384_BLOCK_LENGTH 128 63 | #define SHA384_DIGEST_LENGTH 48 64 | #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) 65 | #define SHA512_BLOCK_LENGTH 128 66 | #define SHA512_DIGEST_LENGTH 64 67 | #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) 68 | 69 | 70 | /*** SHA-256/384/512 Context Structures *******************************/ 71 | typedef struct _SHA256_CTX 72 | { 73 | uint32_t state[8]; 74 | uint64_t bitcount; 75 | uint8_t buffer[SHA256_BLOCK_LENGTH]; 76 | } SHA256_CTX; 77 | 78 | void SHA256_Init(SHA256_CTX *); 79 | void SHA256_Update(SHA256_CTX *, const uint8_t *, size_t); 80 | void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX *); 81 | 82 | #endif /* _SHA2_H */ 83 | -------------------------------------------------------------------------------- /crc32.h: -------------------------------------------------------------------------------- 1 | static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ 2 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 3 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 4 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 5 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 6 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 7 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 8 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 9 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 10 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 11 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 12 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 13 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 14 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 15 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 16 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 17 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 18 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 19 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 20 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 21 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 22 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 23 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 24 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 25 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 26 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 27 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 28 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 29 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 30 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 31 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 32 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 33 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 34 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 35 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 36 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 37 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 38 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 39 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 40 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 41 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 42 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 43 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 44 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 45 | }; 46 | 47 | #define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) 48 | 49 | uint32_t crc32buf(char *buf, size_t len) 50 | { 51 | uint32_t crc; 52 | 53 | crc = 0xFFFFFFFF; 54 | 55 | for ( ; len; --len, ++buf) 56 | { 57 | crc = UPDC32(*buf, crc); 58 | } 59 | 60 | return crc; 61 | } 62 | -------------------------------------------------------------------------------- /faifa_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Faifa library private interface 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __FAIFA_PRIV_H__ 53 | #define __FAIFA_PRIV_H__ 54 | 55 | #include 56 | #include 57 | #include 58 | #ifdef DARWIN 59 | #include 60 | #include 61 | #endif 62 | 63 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 64 | 65 | #ifndef UNUSED 66 | # if defined(__GNUC__) 67 | # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) 68 | # elif defined(__LCLINT__) 69 | # define UNUSED(x) /*@unused@*/ x 70 | # else 71 | # define UNUSED(x) x 72 | # endif 73 | #endif 74 | 75 | #ifdef __cplusplus 76 | extern "C" { 77 | #endif 78 | 79 | struct faifa { 80 | char ifname[IFNAMSIZ]; 81 | pcap_t *pcap; 82 | char error[256]; 83 | u_int8_t dst_addr[ETHER_ADDR_LEN]; 84 | int verbose; 85 | }; 86 | 87 | extern void faifa_set_error(faifa_t *faifa, char *format, ...); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif /* __FAIFA_PRIV_H__ */ 94 | -------------------------------------------------------------------------------- /crypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Cryptographic headers 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __CRYPTO_H__ 53 | #define __CRYPTO_H__ 54 | 55 | #include 56 | 57 | #define MAX_SECRET_SIZ 64 58 | #define SALT_SIZ 8 59 | 60 | extern u_int8_t dak_salt[SALT_SIZ]; 61 | extern u_int8_t nmk_salt[SALT_SIZ]; 62 | 63 | /** 64 | * salted_secret 65 | * @len: lenght of the salted secret 66 | * @value: value of the salted secret 67 | */ 68 | struct salted_secret { 69 | u_int8_t len; 70 | u_int8_t value[72]; 71 | }; 72 | 73 | /** 74 | * sha256_ctx 75 | * @total: total of the sha256 context 76 | * @state: state of the context 77 | * @buffer: buffer to calculate stuff 78 | */ 79 | struct sha256_ctx { 80 | u_int32_t total[2]; 81 | u_int32_t state[8]; 82 | u_int8_t buffer[MAX_SECRET_SIZ]; 83 | }; 84 | 85 | 86 | /** 87 | * gen_passphrase - create a hash from a user input passphrase 88 | * @password: user input password 89 | * @key: resulting key 90 | * @salt: salt type (NMK, DAK or NID) 91 | * @return 92 | * 0 on success, -1 on failure 93 | */ 94 | extern int gen_passphrase(const char *password, u_int8_t *key, const unsigned char *salt); 95 | 96 | #endif /* __CRYPTO_H__ */ 97 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the faifa program and library 3 | # 4 | # 5 | # Copyright (C) 2007-2009 6 | # Xavier Carcelle 7 | # Florian Fainelli 8 | # Nicolas Thill 9 | # 10 | # License: 11 | # GPLv2 12 | # 13 | 14 | CC = @CC@ 15 | STRIP ?= $(CROSS)strip 16 | CFLAGS = @CFLAGS@ 17 | LDFLAGS = @LDFLAGS@ 18 | INSTALL = @INSTALL@ 19 | LIBS = @LIBS@ 20 | 21 | prefix = @prefix@ 22 | exec_prefix = @exec_prefix@ 23 | sbindir = @sbindir@ 24 | mandir = @mandir@ 25 | libdir = @libdir@ 26 | datarootdir = @datarootdir@ 27 | includedir = @includedir@ 28 | 29 | OS?=$(shell uname -s | tr a-z A-Z) 30 | APP:=faifa 31 | GIT_REV?=$(shell git describe --exact-match 2> /dev/null || echo "`git symbolic-ref HEAD 2> /dev/null | cut -b 12-`-`git log --pretty=format:\"%h\" -1`") 32 | ifeq ($(GIT_REV),) 33 | GIT_REV=HEAD 34 | endif 35 | 36 | # Object files for the library 37 | LIB_OBJS:=faifa.o frame.o crypto.o sha2.o 38 | LIB_NAME:=lib$(APP).a 39 | LIB_SHARED_SO:=lib$(APP).so 40 | LIB_SONAME:=$(LIB_SHARED_SO).0 41 | 42 | # Object files for the program 43 | OBJS:= main.o 44 | HEADERS:= faifa.h faifa_compat.h faifa_priv.h homeplug.h homeplug_av.h crypto.h device.h endian.h 45 | 46 | # Objects for hpav_cfg 47 | HPAV_CFG_OBJS:=sha2.o hpav_cfg.o crypto.o 48 | 49 | SIM_OBJS:=simulator.o 50 | SIM_LIBS:=-levent 51 | SIM_CFLAGS:=-Wno-unused 52 | 53 | ifeq ($(OS),DARWIN) 54 | LDFLAGS+=-dynamiclib -Wl,-dylib_install_name -Wl,$(LIB_SONAME) 55 | endif 56 | 57 | LIBS:=$(LDFLAGS) $(LIBS) 58 | 59 | ifeq ($(OS),CYGWIN_NT-5.1) 60 | LIBS+=-lwpcap 61 | APP:=$(APP).exe 62 | else 63 | CFLAGS+= -fPIC 64 | endif 65 | 66 | man8dir = $(mandir)/man8 67 | # Man page 68 | MANTYP=8 69 | MANFIL=$(APP).8.gz 70 | 71 | all: $(APP) $(LIB_NAME) $(LIB_SONAME) hpav_cfg simulator 72 | 73 | hpav_cfg: $(HPAV_CFG_OBJS) 74 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(HPAV_CFG_OBJS) 75 | 76 | simulator: $(SIM_OBJS) 77 | $(CC) $(CFLAGS) $(SIM_CFLAGS) $(LDFLAGS) -o $@ $(SIM_OBJS) $(SIM_LIBS) 78 | 79 | $(APP): $(OBJS) $(HEADERS) $(LIB_SONAME) 80 | $(CC) -D$(OS) -DGIT_REV="\"$(GIT_REV)\"" $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LIB_SONAME) 81 | 82 | $(LIB_NAME): $(LIB_OBJS) $(HEADERS) 83 | $(AR) rcs $(LIB_NAME) $(LIB_OBJS) 84 | 85 | $(LIB_SONAME): $(LIB_OBJS) $(HEADERS) 86 | $(CC) -shared -Wl,-soname,$(LIB_SONAME) -o $(LIB_SONAME) $(LIB_OBJS) $(LIBS) 87 | 88 | %.o: %.c $(HEADERS) 89 | $(CC) -D$(OS) -DGIT_REV="\"$(GIT_REV)\"" $(CFLAGS) -c $< 90 | 91 | clean: 92 | rm -f $(APP) \ 93 | *.o \ 94 | *.a \ 95 | *.so* \ 96 | $(MANFIL) 97 | 98 | autoclean: 99 | -rm -f configure config.log config.status Makefile 100 | 101 | distclean: clean autoclean 102 | 103 | install: installman strip 104 | $(INSTALL) -d $(DESTDIR)$(sbindir) 105 | $(INSTALL) -m0755 $(APP) $(DESTDIR)$(sbindir) 106 | $(INSTALL) -m0755 hpav_cfg $(DESTDIR)$(sbindir) 107 | $(INSTALL) -d $(DESTDIR)$(libdir) 108 | $(INSTALL) -m0644 $(LIB_SONAME) $(DESTDIR)$(libdir) 109 | $(INSTALL) -d $(DESTDIR)$(includedir)/faifa 110 | cp $(HEADERS) $(DESTDIR)$(includedir)/faifa 111 | cd $(DESTDIR)$(libdir) && ln -sf $(LIB_SONAME) $(LIB_SHARED_SO) 112 | 113 | strip: $(APP) $(LIB_SONAME) 114 | $(STRIP) $(APP) 115 | $(STRIP) $(LIB_SONAME) 116 | 117 | man: 118 | -rm -f $(MANFIL) 119 | gzip -c -q -9v $(APP).$(MANTYP) > $(MANFIL) 120 | 121 | installman: man 122 | $(INSTALL) -d $(DESTDIR)$(man8dir) 123 | $(INSTALL) -m0644 $(MANFIL) $(DESTDIR)$(man8dir) 124 | 125 | uninstallman: 126 | -rm -f $(DESTDIR)$(man8dir)/$(MANFIL) 127 | 128 | uninstall: uninstallman 129 | -rm -f $(DESTDIR)$(sbindir)/$(APP) 130 | -rm -f $(DESTDIR)$(sbindir)/hpav_cfg 131 | -rm -f $(DESTDIR)$(libdir)/$(LIB_SONAME) 132 | -rm -f $(DESTDIR)$(libdir)/$(LIB_SHARED_SO) 133 | -rm -rf $(DESTDIR)$(includedir)/faifa 134 | 135 | .PHONY: 136 | clean 137 | -------------------------------------------------------------------------------- /faifa_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Faifa library compatibility layer 3 | * 4 | * Copyright (C) 2007-2009 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __FAIFA_COMPAT_H__ 53 | #define __FAIFA_COMPAT_H__ 54 | 55 | #ifndef ETHERTYPE_8021Q 56 | # define ETHERTYPE_8021Q 0x8100 57 | #endif 58 | 59 | #define ETH_ZLEN 60 /* Min. octets in frame w/o FCS */ 60 | 61 | #ifdef __CYGWIN__ 62 | #define PCAP_SRC_IF_STRING "rpcap://" 63 | 64 | #define ETH_ALEN 6 65 | #define ETHER_CRC_LEN 4 66 | #define ETH_FRAME_LEN 1514 67 | #define ETHER_ADDR_LEN ETH_ALEN 68 | #define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN) /* max packet length */ 69 | 70 | /* This is a name for the 48 bit ethernet address available on many 71 | * systems. */ 72 | struct ether_addr 73 | { 74 | u_int8_t ether_addr_octet[ETH_ALEN]; 75 | } __attribute__ ((__packed__)); 76 | 77 | /* 10Mb/s ethernet header */ 78 | struct ether_header 79 | { 80 | u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ 81 | u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */ 82 | u_int16_t ether_type; /* packet type ID field */ 83 | } __attribute__ ((__packed__)); 84 | 85 | #else 86 | #include 87 | #endif 88 | 89 | #endif /* __FAIFA_COMPAT_H__ */ 90 | -------------------------------------------------------------------------------- /copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Florian Fainelli on 2 | Sun, 18 May 2008 11:29:24 +0200. 3 | 4 | It was downloaded from https://dev.open-plc.org 5 | 6 | Upstream Author: 7 | Xavier Carcelle 8 | Nicolas Thill 9 | Florian Fainelli 10 | 11 | Copyright: 12 | Copyright (C) 2007-2008 Xavier Carcelle 13 | Florian Fainelli 14 | Nicolas Thill 15 | 16 | License: 17 | GPL (v2 or later) 18 | 19 | This program is free software; you can redistribute it and/or modify 20 | it under the terms of the GNU General Public License as published by 21 | the Free Software Foundation; either version 2 of the License, or 22 | (at your option) any later version. 23 | 24 | This program is distributed in the hope that it will be useful, 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 | GNU General Public License for more details. 28 | 29 | You should have received a copy of the GNU General Public License 30 | along with this program; if not, write to the Free Software 31 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 32 | 33 | This program is free software; you can redistribute it and/or 34 | modify it under the terms of the GNU General Public License as 35 | published by the Free Software Foundation; either version 2 of the 36 | License, or (at your option) any later version. 37 | 38 | This program is distributed in the hope that it will be useful, but 39 | is provided AS IS, WITHOUT ANY WARRANTY; without even the implied 40 | warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and 41 | NON-INFRINGEMENT. See the GNU General Public License for more details. 42 | 43 | You should have received a copy of the GNU General Public License 44 | along with this program; if not, write to the Free Software 45 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, 46 | MA 02111-1307, USA. 47 | 48 | In addition, as a special exception, the copyright holders give 49 | permission to link the code of portions of this program with the 50 | OpenSSL library under certain conditions as described in each 51 | individual source file, and distribute linked combinations 52 | including the two. 53 | You must obey the GNU General Public License in all respects 54 | for all of the code used other than OpenSSL. If you modify 55 | file(s) with this exception, you may extend this exception to your 56 | version of the file(s), but you are not obligated to do so. If you 57 | do not wish to do so, delete this exception statement from your 58 | version. If you delete this exception statement from all source 59 | files in the program, then also delete it here. 60 | 61 | 62 | Certain source files in this program permit linking with the OpenSSL 63 | library (http://www.openssl.org), which otherwise wouldn't be allowed 64 | under the GPL. For purposes of identifying OpenSSL, most source files 65 | giving this permission limit it to versions of OpenSSL having a license 66 | identical to that listed in this file (LICENSE.OpenSSL). It is not 67 | necessary for the copyright years to match between this file and the 68 | OpenSSL version in question. However, note that because this file is 69 | an extension of the license statements of these source files, this file 70 | may not be changed except with permission from all copyright holders 71 | of source files in this program which reference this file. 72 | 73 | On Debian system the full text of the GPL V2, can be 74 | found in `/usr/share/common-licenses/GPL-2'. 75 | 76 | 77 | The Debian packaging is 78 | Copyright (C) 2008, Florian Fainelli 79 | Copyright (C) 2009, Damien Raude-Morvan 80 | and is licensed under the GPL V2 or later, see `/usr/share/common-licenses/GPL-2'. 81 | -------------------------------------------------------------------------------- /faifa.h.8: -------------------------------------------------------------------------------- 1 | .TH FAIFA.H 8 "April 2008" Linux "User manual" 2 | .SH NAME 3 | faifa.h \- Public interface for the Faifa library 4 | .SH DESCRIPTION 5 | faifa.h describes the public interface of the faifa library 6 | 7 | .B 8 | Faifa operations 9 | 10 | Faifa basically performs 3 main operations : 11 | 12 | - send all vendor and protocol specific frames with the corresponding parameters 13 | .br 14 | - dump all vendor and HomePlug 1.0/AV frames with the appropriate frame parsing 15 | .br 16 | - discover the HPAV network topology 17 | 18 | The available vendor specific operations are stored in an array of struct hpav_frame_ops. For each entry the mmtype and the description is specified, with possible callbacks to handle frame initialization and dump function. 19 | 20 | .B 21 | Using the faifa library 22 | 23 | Faifa is also provided as shared library (so file) and static library (a) so that you can link programs with to send HomePlug AV frames. The library allows you, specifying a given mmtype to send the corresponding HPAV frame to a given device. 24 | 25 | .B 26 | Linking with faifa 27 | 28 | You should include faifa.h into your C source file and can directly call functions that are provided by the faifa library. When linking with the faifa library, make sure your linker flags include "-lfaifa" or the absolute path of the shared object to make sure your program will successfully link. 29 | An example makefile could look like: 30 | 31 | all: test 32 | LIBS:=-lm -ltest -lfaifa 33 | $(CC) -D$(OS) $(CFLAGS) -o $@ $(OBJS) $(LIBS) 34 | 35 | .B 36 | Prototypes 37 | 38 | Below are the prototypes provided by the faifa library that you may want to use, though frame.h should be more appropriate for higher-level function handling. 39 | Most of the functions here are juste wrappers to the PCAP library. 40 | 41 | .B 42 | faifa_t - private handle 43 | 44 | typedef struct faifa faifa_t; 45 | 46 | struct faifa { 47 | char ifname[IFNAMSIZ]; 48 | pcap_t *pcap; 49 | char error[256]; 50 | }; 51 | 52 | The faifa private handler is a structure wich stores commonly used variables such as the interface name, a libpcap handler for all packet related informations and the pcap error code. 53 | This structure is initialised on startup of the program. 54 | 55 | .B 56 | faifa_t *faifa_init(void) 57 | 58 | Initialize the faifa private handle of the library. Returns a private handle on success, NULL on error. 59 | 60 | This function should be called at the very beginning of your program, i.e : right after parsing command line arguments for instance. 61 | 62 | .B 63 | void faifa_free(faifa_t *faifa) 64 | 65 | Free the faifa library and dereferences all the private handle members. 66 | 67 | This function should be called on the error path of your program or while closing it. 68 | 69 | .B 70 | char *faifa_error(faifa_t *faifa); 71 | 72 | Return a text message related to the last error. 73 | 74 | .B 75 | int faifa_open(faifa_t *faifa, char *name); 76 | 77 | Open specified network device. Returns 0 on success, -1 on error 78 | 79 | This function will verify that the interface is an Ethernet link layer interface, that it exists 80 | and is up and running. These operations required root or similar priviledges. 81 | 82 | .B 83 | int faifa_close(faifa_t *faifa); 84 | 85 | Close network device. Returns 0 on success, -1 on error. 86 | 87 | .B 88 | int faifa_send(faifa_t *faifa, void *buf, int len) 89 | 90 | Send raw ethernet frame on the interface. Returns the number of bytes sent on success, -1 on error. 91 | 92 | This function will send a raw ethernet frame (see faifa(8) for more informations) therefore letting you 93 | total control over the frame you wish to send. Additionnal checks should be performed if your ethernet 94 | protocol requires more checkings. 95 | 96 | .B 97 | int faifa_recv(faifa_t *faifa, void *buf, int len) 98 | 99 | Receive raw ethernet frame. Returns the number of bytes received on success, -1 on error. 100 | 101 | This function opens the network interface in non-blocking read mode, therefore letting you start another 102 | capture program. 103 | 104 | .B 105 | void (*faifa_loop_handler_t)(faifa_t *faifa, void *buf, int len, void *user) 106 | 107 | Receive and dispatch frames in a loop. This function helps you dispatch received frames 108 | to a local function based on the buffer contents. 109 | 110 | .SH SEE ALSO 111 | .BR faifa(8) 112 | .SH AUTHOR 113 | Florian Fainelli , Xavier Carcelle 114 | -------------------------------------------------------------------------------- /crypto.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cryptographic routines for faifa using standalone SHA2 3 | * 4 | * Copyright (C) 2008 Florian Fainelli 5 | * 6 | * The BSD License 7 | * =============== 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 19 | * contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 26 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | /* 36 | * In addition, as a special exception, the copyright holders give 37 | * permission to link the code of portions of this program with the 38 | * OpenSSL library under certain conditions as described in each 39 | * individual source file, and distribute linked combinations 40 | * including the two. 41 | * You must obey the GNU General Public License in all respects 42 | * for all of the code used other than OpenSSL. If you modify 43 | * file(s) with this exception, you may extend this exception to your 44 | * version of the file(s), but you are not obligated to do so. If you 45 | * do not wish to do so, delete this exception statement from your 46 | * version. If you delete this exception statement from all source 47 | * files in the program, then also delete it here. 48 | */ 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include "crypto.h" 56 | #include "sha2.h" 57 | 58 | #define HASH_SIZ SHA256_DIGEST_LENGTH 59 | 60 | unsigned char hash_value[HASH_SIZ]; 61 | 62 | u_int8_t dak_salt[SALT_SIZ] = {0x08, 0x85, 0x6D, 0xAF, 0x7C, 0xF5, 0x81, 0x85}; 63 | u_int8_t nmk_salt[SALT_SIZ] = {0x08, 0x85, 0x6D, 0xAF, 0x7C, 0xF5, 0x81, 0x86}; 64 | 65 | 66 | /** 67 | * init_salted_secret - initialise a secret using a salt 68 | * @secret: secret to initialise will be modified 69 | * @isecret: initialisation secret 70 | * @salt: secret to initialise with 71 | */ 72 | void init_salted_secret(struct salted_secret *secret, const unsigned char *isecret, const unsigned char *isalt) 73 | { 74 | unsigned char l = ' '; 75 | 76 | secret->len = 0; 77 | memset(secret->value, 0, sizeof(secret->value)); 78 | 79 | if (isecret) { 80 | l = (unsigned char)strlen((char *)isecret); 81 | if (l > MAX_SECRET_SIZ) 82 | l = MAX_SECRET_SIZ; 83 | 84 | memcpy(secret->value, isecret, l); 85 | } 86 | 87 | if (!isalt) 88 | l = 16; 89 | 90 | secret->len = (unsigned char) (secret->len + l); 91 | 92 | if (isalt) { 93 | memcpy(&secret->value[secret->len], (unsigned char*)isalt, SALT_SIZ); 94 | secret->len += SALT_SIZ; 95 | } 96 | } 97 | 98 | /** 99 | * hash_hpav - hash a secret with a salt as HomePlug AV requires it 100 | * @isecret: initialisation secret 101 | * @salt: salt to initialise the secret with 102 | */ 103 | const unsigned char* hash_hpav(const unsigned char* isecret, const unsigned char *salt) 104 | { 105 | SHA256_CTX context; 106 | struct salted_secret secret; 107 | int i, max; 108 | 109 | /* Null salt is the NetworkID */ 110 | if (!salt) 111 | max = 4; 112 | else 113 | max = 999; 114 | 115 | SHA256_Init(&context); 116 | memset(hash_value, 0, sizeof(hash_value)); 117 | 118 | init_salted_secret(&secret, isecret, salt); 119 | SHA256_Update(&context, secret.value, secret.len); 120 | SHA256_Final(hash_value, &context); 121 | 122 | /* Do it 998 times as the standard requires it 123 | * or only 4 times if we use the NID */ 124 | for(i = 0; i < max; i++) { 125 | SHA256_Init(&context); 126 | SHA256_Update(&context, hash_value, HASH_SIZ); 127 | SHA256_Final(hash_value, &context); 128 | } 129 | 130 | return hash_value; 131 | } 132 | 133 | int gen_passphrase(const char *password, u_int8_t *key, const unsigned char *salt) 134 | { 135 | u_int8_t password_cpy[MAX_SECRET_SIZ + 1]; 136 | const unsigned char *password_hash; 137 | 138 | /* Use a local variable to store the input password */ 139 | memcpy(password_cpy, password, MAX_SECRET_SIZ); 140 | 141 | password_hash = hash_hpav(password_cpy, salt); 142 | memcpy(key, password_hash, 16); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /homeplug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Homeplug 1.0 Ethernet frame definitions 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __HOMEPLUG_H__ 53 | #define __HOMEPLUG_H__ 54 | 55 | #include 56 | 57 | #define ETHERTYPE_HOMEPLUG 0x887b 58 | 59 | 60 | /** 61 | * hp10_mmentry - HomePlug 1.0 MAC Management Entry (MME) 62 | * @mmetype: MME type 63 | * @mmelength: MME data length 64 | * @mmedata: MME data 65 | */ 66 | struct hp10_mmentry { 67 | u_int8_t mmetype:5; 68 | u_int8_t mmeversion:3; 69 | u_int8_t mmelength; 70 | u_int8_t mmedata[0]; 71 | } __attribute__((__packed__)); 72 | 73 | /** 74 | * hp10_frame - HomePlug 1.0 frame 75 | * @mecount: Number of MAC entries in this frame 76 | * @mentries: MAC Entries 77 | */ 78 | struct hp10_frame { 79 | u_int8_t mmecount:7; 80 | u_int8_t reserved:1; 81 | struct hp10_mmentry mmentries[0]; 82 | } __attribute__((__packed__)); 83 | 84 | /** 85 | * hp10_frame_ops - Homeplug 1.0 ethernet frames operations 86 | * @mmtype: frame specific MM type 87 | * @desc: frame description 88 | * @init_frame: frame specific initialisation callback 89 | * @dump_frame: frame specific dump callback 90 | */ 91 | struct hp10_frame_ops { 92 | u_int8_t mmtype; 93 | char *desc; 94 | int (*init_frame)(void *buf, int len, void *user); 95 | int (*dump_frame)(void *buf, int len); 96 | }; 97 | 98 | 99 | /* 00 - Channel Estimation Request */ 100 | struct hp10_channel_estimation_request { 101 | u_int8_t reserved1:4; 102 | u_int8_t version:4; 103 | } __attribute__((__packed__)); 104 | 105 | /* 08 - Network parameters Confirm */ 106 | struct hp10_parameters_stats_confirm { 107 | u_int16_t tx_ack_cnt; 108 | u_int16_t tx_nack_cnt; 109 | u_int16_t tx_fail_cnt; 110 | u_int16_t tx_cont_loss_cnt; 111 | u_int16_t tx_coll_cnt; 112 | u_int16_t tx_ca3_cnt; 113 | u_int16_t tx_ca2_cnt; 114 | u_int16_t tx_ca1_cnt; 115 | u_int16_t tx_ca0_cnt; 116 | u_int32_t rx_cumul; 117 | } __attribute__((__packed__)); 118 | 119 | /* 1a - Network statistics Confirm */ 120 | struct hp10_tonemap { 121 | u_int8_t netw_da[6]; 122 | u_int16_t bytes40; 123 | u_int16_t fails; 124 | u_int16_t drops; 125 | } __attribute__((__packed__)); 126 | 127 | #define HP10_NUM_TONE_MAP 15 128 | 129 | /* 1c - Extended network statistics Confirm */ 130 | struct hp10_network_stats_confirm { 131 | u_int8_t icid:7; 132 | u_int8_t ac:1; 133 | u_int16_t bytes40_robo; 134 | u_int16_t fails_robo; 135 | u_int16_t drops_robo; 136 | struct hp10_tonemap nstone[HP10_NUM_TONE_MAP]; 137 | } __attribute__((__packed__)); 138 | 139 | /* 1f - Performance statistics confirm */ 140 | struct hp10_perf_stats_confirm { 141 | u_int8_t rsvd:7; 142 | u_int8_t perf_ctrl:1; 143 | u_int16_t max_delay; 144 | u_int16_t max_delay_jitter_ca[4]; 145 | u_int16_t max_latency_ca[4]; 146 | u_int16_t max_latency_bin_ca0[10]; 147 | u_int16_t max_latency_bin_ca1[10]; 148 | u_int16_t max_latency_bin_ca2[10]; 149 | u_int16_t max_latency_bin_ca3[10]; 150 | u_int16_t rst_cnt; 151 | u_int16_t txack; // [31 - 16] 152 | u_int16_t txnack; // [31 - 16] 153 | u_int16_t txcoll; // [31 - 16] 154 | u_int16_t tcloss; // [31 - 16] 155 | u_int16_t txcalat[4]; // [31 - 16] 156 | u_int16_t rxbp40; //[63 - 32] 157 | } __attribute__((__packed__)); 158 | 159 | #endif /* __INTELLON_H__ */ 160 | -------------------------------------------------------------------------------- /faifa.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Faifa library public interface 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #ifndef __FAIFA_H__ 53 | #define __FAIFA_H__ 54 | 55 | #include 56 | 57 | #define FAIFA_VERSION_MAJOR 0 58 | #define FAIFA_VERSION_MINOR 1 59 | 60 | #define faifa_printf(stream, fmt,args...) \ 61 | fprintf (stream, fmt ,##args) \ 62 | 63 | #ifdef __cplusplus 64 | extern "C" { 65 | #endif 66 | 67 | /** 68 | * faifa_t - private handle 69 | */ 70 | typedef struct faifa faifa_t; 71 | 72 | /** 73 | * faifa_init - init library 74 | * @return 75 | * private handle on success, NULL on error 76 | */ 77 | extern faifa_t *faifa_init(void); 78 | 79 | /** 80 | * faifa_free - free library 81 | * @faifa: private handle 82 | */ 83 | extern void faifa_free(faifa_t *faifa); 84 | 85 | /** 86 | * faifa_error - return a text message related to the last error 87 | * @faifa: private handle 88 | * @return 89 | * error message string 90 | */ 91 | extern char *faifa_error(faifa_t *faifa); 92 | 93 | /** 94 | * faifa_open - open specified network device 95 | * @faifa: private handle 96 | * @name: network device name 97 | * @return 98 | * 0 on success, -1 on error 99 | */ 100 | extern int faifa_open(faifa_t *faifa, char *name); 101 | 102 | /** 103 | * faifa_close - close network device 104 | * @faifa: private handle 105 | * @return 106 | * 0 on success, -1 on error 107 | */ 108 | extern int faifa_close(faifa_t *faifa); 109 | 110 | /** 111 | * faifa_send - send raw ethernet frame 112 | * @faifa: private handle 113 | * @buf: data buffer 114 | * @len: data buffer length 115 | * @return 116 | * number of bytes sent on success, -1 on error 117 | */ 118 | extern int faifa_send(faifa_t *faifa, void *buf, int len); 119 | 120 | /** 121 | * faifa_recv - receive raw ethernet frame 122 | * @faifa: private handle 123 | * @buf: data buffer 124 | * @len: data buffer length 125 | * @return 126 | * number of bytes received on success, -1 on error 127 | */ 128 | extern int faifa_recv(faifa_t *faifa, void *buf, int len); 129 | 130 | /** 131 | * faifa_loop_handler_t - packet dispatch handler 132 | */ 133 | typedef void (*faifa_loop_handler_t)(faifa_t *faifa, void *buf, int len, void *user); 134 | 135 | /** 136 | * faifa_loop - receive and dispatch frames in a loop 137 | * @faifa: private handle 138 | * @handler: frame dispatch handler 139 | * @user: user value passed to the dispatch handler 140 | * @return 141 | * 0 on success, -1 on error 142 | */ 143 | extern int faifa_loop(faifa_t *faifa, faifa_loop_handler_t handler, void *user); 144 | 145 | 146 | extern int faifa_sprint_hex(char *str, void *buf, int len, char *sep); 147 | 148 | /** 149 | * faifa_parse_mac_addr - parses a MAC address 150 | * @faifa: private handle 151 | * @mac: mac address as a string 152 | * @addr: mac address as a 6-bytes buffer 153 | * @return 154 | * 0 on success, -1 on error 155 | */ 156 | extern int faifa_parse_mac_addr(faifa_t *faifa, const char *mac, u_int8_t *addr); 157 | 158 | /** 159 | * faifa_set_dst_addr - sets the destination MAC address 160 | * @faifa: private handle 161 | * @mac: destination MAC address 162 | * 163 | */ 164 | extern void faifa_set_dst_addr(faifa_t *faifa, const u_int8_t *addr); 165 | 166 | /** 167 | * faifa_set_verbose - set the faifa verbosity 168 | * @faifa: private handle 169 | * @verbose: verbosity level 170 | */ 171 | extern void faifa_set_verbose(faifa_t *faifa, int verbose); 172 | 173 | static inline int faifa_is_zero_ether_addr(const u_int8_t *addr) 174 | { 175 | return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); 176 | } 177 | 178 | #ifdef __cplusplus 179 | } 180 | #endif 181 | 182 | #endif /* __FAIFA_H__ */ 183 | -------------------------------------------------------------------------------- /faifa.8: -------------------------------------------------------------------------------- 1 | .TH FAIFA 8 "April 2011" Linux "User manual" 2 | .SH NAME 3 | faifa \- configure HomePlug 1.0/AV devices 4 | .SH SYNOPSIS 5 | .B faifa [OPTIONS] 6 | .br 7 | \-i specify network interface to use 8 | .br 9 | \-m show the menu asking for known MM types 10 | .br 11 | \-a destination MAC address to send frames to 12 | .br 13 | \-k network key to set 14 | .br 15 | \-v be verbose (default: no) 16 | .br 17 | \-e set error stream (default: stderr) 18 | .br 19 | \-o set output stream (default: stdout) 20 | .br 21 | \-s set input stream (default: stdin) 22 | .br 23 | \-h show the usage 24 | .br 25 | .SH DESCRIPTION 26 | faifa can configure any PowerLine Communication device using the Homeplug AV / AV2 protocol. Initially this meant the Intellon (now Qualcomm Atheros) INT5000 and INT6000 HomePlug AV (200Mbits) chips but it also works with newer devices. In order to use it with Broadcom Homeplug adapters it is necessary to set the destination MAC address to either the adapter address or the broadcast address, they do not respond to the default Intellon address. It supports all Intellon-specific management and control frames. 27 | 28 | .SH "MENU COMMANDS" 29 | \-i specify network interface to use 30 | .br 31 | \-m show the menu asking for known MM types 32 | .br 33 | \-a destination MAC address to send frames to 34 | .br 35 | \-k network key to set 36 | .br 37 | \-v be verbose (default: no) 38 | .br 39 | \-e set error stream (default: stderr) 40 | .br 41 | \-o set output stream (default: stdout) 42 | .br 43 | \-s set input stream (default: stdin) 44 | .br 45 | \-h show the usage 46 | 47 | .TP 48 | .B "HomePlug AV protocol" 49 | 50 | The HomePlug AV protocol was developed by Intellon and specifies how the powerline PHY layer and HPAV MAC layer can converge to allow Ethernet frames to be sent on the medium. It handles all the low-level modulation and constellation building plus the Medium Access Control handling between devices. 51 | The HomePlug AV network topology consists of one coordinator (called CCo) for a given logical HPAV network (i.e: with the same Network Encryption Key) and none or several stations (called STAs). Other devices can have a specific role which is a bridge, between several logical networks. 52 | 53 | 54 | ------------------------------------ 55 | .br 56 | | HomePlug PHY | 57 | .br 58 | ------------------------------------ 59 | .br 60 | | HomePlug MAC convergence layer | 61 | .br 62 | ------------------------------------ 63 | .br 64 | | Ethernet MAC layer | 65 | .br 66 | ------------------------------------ 67 | .br 68 | 69 | It is possible to configure the HPAV MAC convergence layer by using specific Ethernet frames with the 0x88e1 Ethertype. Such frames will be interpreted by the Intellon controller present in the devices and are known as control or management frames. 70 | 71 | Such frames can be either protocol specific (i.e: common to all HPAV implementations) or vendor specific. There is no convention to specify whether an HPAV configuration and management frame is vendor specific or not. Most implementations will share a common format for basic network operations like setting the Network Management Key or the Encryption Key. 72 | 73 | A HomePlug AV management frame is described below : 74 | 75 | 8 bits 16 bits 76 | .br 77 | --------------------------------------------------- 78 | .br 79 | | MM version | MM type | 80 | .br 81 | --------------------------------------------------- 82 | .br 83 | | OUI (24 bits) | 84 | .br 85 | --------------------------------------------------- 86 | .br 87 | | Payload (var) | 88 | .br 89 | --------------------------------------------------- 90 | 91 | The payload is highly dependent on the implementation though most vendors will try to define a common template for it. Such management frame should be encapsulated in standard ethernet frames with the 0x88e1 ethertype. 92 | 93 | 94 | .B 95 | Faifa operations 96 | 97 | Faifa basically performs 3 main operations : 98 | 99 | \- send all vendor and protocol specific frames with the corresponding parameters 100 | .br 101 | \- dump all vendor and HomePlug 1.0/AV frames with the appropriate frame parsing 102 | .br 103 | \- discover the HPAV network topology 104 | 105 | The available vendor specific operations are stored in an array of struct hpav_frame_ops. For each entry the mmtype and the description is specified, with possible callbacks to handle frame initialization and dump function. 106 | 107 | .B 108 | Using the faifa library 109 | 110 | Faifa is also provided as shared library (so file) and static library so that you can link programs with to send HomePlug AV frames. The library allows you, specifying a given mmtype to send the corresponding HPAV frame to a given device. 111 | 112 | .B 113 | Linking with faifa 114 | 115 | You should include faifa.h into your C source file and then you can directly call functions that are provided by the faifa library. When linking with the faifa library, make sure your linker flags include "\-lfaifa" or the absolute path of the shared object to make sure your program will successfully link. 116 | 117 | .B 118 | Sending frames using do_frame 119 | 120 | The main function you want to call is do_frame and pass it the MMtype and destination MAC address you want to send the frame to. This function will : 121 | 122 | \- lookup the mmtype by reading the array containing available frame operations 123 | .br 124 | \- initialize the frame header (MM version, type, source and destination MAC addresses) 125 | .br 126 | \- call the initialisation function (if needed) to let the user input the parameters (or any other input method) 127 | .br 128 | \- calculate the appropriate frame size 129 | .br 130 | \- send it to the device 131 | .br 132 | \- close the network socket descriptor 133 | 134 | This function propagates the return code from the write command on the socket descriptor. 135 | 136 | .B 137 | Receiving frames using do_receive_frame 138 | 139 | This function will listen for received frames on the specified interface and will : 140 | 141 | \- check that the ethertype is set to 0x88e1 otherwise it will discard the frame 142 | .br 143 | \- cast the received packet to an HPAV management frame structure 144 | .br 145 | \- lookup for the received MM type into the arrays of known response/indications 146 | .br 147 | \- call the frame parsing function (based on the mmtype) accordingly 148 | 149 | You will probably want to set the network descriptor in reading mode non-blocking. Faifa uses this function with a call to a pcap_loop method inside a dedicated thread to receive all frames. 150 | 151 | .SH SEE ALSO 152 | .BR ifconfig(8) 153 | .SH AUTHORS 154 | Florian Fainelli , Xavier Carcelle , Nicolas Thill 155 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Program entry and command line parsing 3 | * 4 | * Copyright (C) 2007-2008 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * In addition, as a special exception, the copyright holders give 39 | * permission to link the code of portions of this program with the 40 | * OpenSSL library under certain conditions as described in each 41 | * individual source file, and distribute linked combinations 42 | * including the two. 43 | * You must obey the GNU General Public License in all respects 44 | * for all of the code used other than OpenSSL. If you modify 45 | * file(s) with this exception, you may extend this exception to your 46 | * version of the file(s), but you are not obligated to do so. If you 47 | * do not wish to do so, delete this exception statement from your 48 | * version. If you delete this exception statement from all source 49 | * files in the program, then also delete it here. 50 | */ 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #include "faifa.h" 58 | #include "faifa_compat.h" 59 | 60 | #ifndef FAIFA_PROG 61 | #define FAIFA_PROG "faifa" 62 | #endif 63 | 64 | /* Command line arguments storing */ 65 | int opt_help = 0; 66 | int opt_interactive = 0; 67 | int opt_key = 0; 68 | extern FILE *err_stream; 69 | extern FILE *out_stream; 70 | extern FILE *in_stream; 71 | 72 | /** 73 | * error - display error message 74 | */ 75 | static void error(char *message) 76 | { 77 | fprintf(stderr, "%s: %s\n", FAIFA_PROG, message); 78 | } 79 | 80 | /** 81 | * usage - show the program usage 82 | */ 83 | static void usage(void) 84 | { 85 | fprintf(stderr, "-i : interface\n" 86 | "-m : show menu (no option required)\n" 87 | "-a : station MAC address\n" 88 | "-k : network key\n" 89 | "-v : be verbose (default: no)\n" 90 | "-e : error stream (default: stderr)\n" 91 | "-o : output stream (default: stdout)\n" 92 | "-s : input stream (default: stdin)\n" 93 | "-h : this help\n"); 94 | } 95 | 96 | extern void menu(faifa_t *faifa); 97 | extern void set_key(char *macaddr); 98 | 99 | /** 100 | * main - main function of faifa 101 | * @argc: number of arguments 102 | * @argv: array of arguments 103 | */ 104 | int main(int argc, char **argv) 105 | { 106 | faifa_t *faifa; 107 | char *opt_ifname = NULL; 108 | char *opt_macaddr = NULL; 109 | char *opt_err_stream = NULL; 110 | char *opt_out_stream = NULL; 111 | char *opt_in_stream = NULL; 112 | int opt_verbose = 0; 113 | int c; 114 | int ret = 0; 115 | u_int8_t addr[ETHER_ADDR_LEN] = { 0 }; 116 | 117 | fprintf(stdout, "Faifa for HomePlug AV (GIT revision %s)\n\n", GIT_REV); 118 | 119 | if (argc < 2) { 120 | usage(); 121 | return -1; 122 | } 123 | 124 | while ((c = getopt(argc, argv, "i:ma:k:ve:o:s:h")) != -1) { 125 | switch (c) { 126 | case 'i': 127 | opt_ifname = optarg; 128 | break; 129 | case 'm': 130 | opt_interactive = 1; 131 | break; 132 | case 'a': 133 | opt_macaddr = optarg; 134 | break; 135 | case 'k': 136 | opt_key = 1; 137 | break; 138 | case 'v': 139 | opt_verbose = 1; 140 | break; 141 | case 'e': 142 | opt_err_stream = optarg; 143 | break; 144 | case 'o': 145 | opt_out_stream = optarg; 146 | break; 147 | case 's': 148 | opt_in_stream = optarg; 149 | break; 150 | case 'h': 151 | default: 152 | opt_help = 1; 153 | break; 154 | } 155 | } 156 | 157 | if (opt_help) { 158 | usage(); 159 | return -1; 160 | } 161 | 162 | if (opt_ifname == NULL) 163 | opt_ifname = "eth0"; 164 | 165 | if (opt_err_stream == NULL) 166 | err_stream = stderr; 167 | else { 168 | err_stream = fopen(opt_err_stream, "w+"); 169 | if (!err_stream) { 170 | perror("err_stream"); 171 | return -1; 172 | } 173 | } 174 | 175 | if (opt_out_stream == NULL) 176 | out_stream = stdout; 177 | else { 178 | out_stream = fopen(opt_out_stream, "w+"); 179 | if (!out_stream) { 180 | perror("out_stream"); 181 | return -1; 182 | } 183 | } 184 | 185 | if (opt_in_stream == NULL) 186 | in_stream = stdin; 187 | else { 188 | in_stream = fopen(opt_in_stream, "rb"); 189 | if (!in_stream) { 190 | perror("in_stream"); 191 | return -1; 192 | } 193 | } 194 | 195 | faifa = faifa_init(); 196 | if (faifa == NULL) { 197 | error("can't initialize Faifa library"); 198 | return -1; 199 | } 200 | 201 | if (faifa_open(faifa, opt_ifname) == -1) { 202 | error(faifa_error(faifa)); 203 | faifa_free(faifa); 204 | return -1; 205 | } 206 | 207 | faifa_set_verbose(faifa, opt_verbose); 208 | 209 | if (opt_macaddr) { 210 | ret = faifa_parse_mac_addr(faifa, opt_macaddr, addr); 211 | if (ret < 0) { 212 | error(faifa_error(faifa)); 213 | goto out_error; 214 | } 215 | 216 | faifa_set_dst_addr(faifa, addr); 217 | } 218 | 219 | if (opt_interactive) 220 | menu(faifa); 221 | 222 | out_error: 223 | faifa_close(faifa); 224 | faifa_free(faifa); 225 | 226 | return ret; 227 | } 228 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5 (mit/util/scripts/install.sh). 5 | # 6 | # Copyright 1991 by the Massachusetts Institute of Technology 7 | # 8 | # Permission to use, copy, modify, distribute, and sell this software and its 9 | # documentation for any purpose is hereby granted without fee, provided that 10 | # the above copyright notice appear in all copies and that both that 11 | # copyright notice and this permission notice appear in supporting 12 | # documentation, and that the name of M.I.T. not be used in advertising or 13 | # publicity pertaining to distribution of the software without specific, 14 | # written prior permission. M.I.T. makes no representations about the 15 | # suitability of this software for any purpose. It is provided "as is" 16 | # without express or implied warranty. 17 | # 18 | # Calling this script install-sh is preferred over install.sh, to prevent 19 | # `make' implicit rules from creating a file called install from it 20 | # when there is no Makefile. 21 | # 22 | # This script is compatible with the BSD install script, but was written 23 | # from scratch. It can only install one file at a time, a restriction 24 | # shared with many OS's install programs. 25 | 26 | 27 | # set DOITPROG to echo to test this script 28 | 29 | # Don't use :- since 4.3BSD and earlier shells don't like it. 30 | doit="${DOITPROG-}" 31 | 32 | 33 | # put in absolute paths if you don't have them in your path; or use env. vars. 34 | 35 | mvprog="${MVPROG-mv}" 36 | cpprog="${CPPROG-cp}" 37 | chmodprog="${CHMODPROG-chmod}" 38 | chownprog="${CHOWNPROG-chown}" 39 | chgrpprog="${CHGRPPROG-chgrp}" 40 | stripprog="${STRIPPROG-strip}" 41 | rmprog="${RMPROG-rm}" 42 | mkdirprog="${MKDIRPROG-mkdir}" 43 | 44 | transformbasename="" 45 | transform_arg="" 46 | instcmd="$mvprog" 47 | chmodcmd="$chmodprog 0755" 48 | chowncmd="" 49 | chgrpcmd="" 50 | stripcmd="" 51 | rmcmd="$rmprog -f" 52 | mvcmd="$mvprog" 53 | src="" 54 | dst="" 55 | dir_arg="" 56 | 57 | while [ x"$1" != x ]; do 58 | case $1 in 59 | -c) instcmd="$cpprog" 60 | shift 61 | continue;; 62 | 63 | -d) dir_arg=true 64 | shift 65 | continue;; 66 | 67 | -m) chmodcmd="$chmodprog $2" 68 | shift 69 | shift 70 | continue;; 71 | 72 | -o) chowncmd="$chownprog $2" 73 | shift 74 | shift 75 | continue;; 76 | 77 | -g) chgrpcmd="$chgrpprog $2" 78 | shift 79 | shift 80 | continue;; 81 | 82 | -s) stripcmd="$stripprog" 83 | shift 84 | continue;; 85 | 86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 87 | shift 88 | continue;; 89 | 90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 91 | shift 92 | continue;; 93 | 94 | *) if [ x"$src" = x ] 95 | then 96 | src=$1 97 | else 98 | # this colon is to work around a 386BSD /bin/sh bug 99 | : 100 | dst=$1 101 | fi 102 | shift 103 | continue;; 104 | esac 105 | done 106 | 107 | if [ x"$src" = x ] 108 | then 109 | echo "install: no input file specified" 110 | exit 1 111 | else 112 | true 113 | fi 114 | 115 | if [ x"$dir_arg" != x ]; then 116 | dst=$src 117 | src="" 118 | 119 | if [ -d $dst ]; then 120 | instcmd=: 121 | chmodcmd="" 122 | else 123 | instcmd=mkdir 124 | fi 125 | else 126 | 127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 128 | # might cause directories to be created, which would be especially bad 129 | # if $src (and thus $dsttmp) contains '*'. 130 | 131 | if [ -f $src -o -d $src ] 132 | then 133 | true 134 | else 135 | echo "install: $src does not exist" 136 | exit 1 137 | fi 138 | 139 | if [ x"$dst" = x ] 140 | then 141 | echo "install: no destination specified" 142 | exit 1 143 | else 144 | true 145 | fi 146 | 147 | # If destination is a directory, append the input filename; if your system 148 | # does not like double slashes in filenames, you may need to add some logic 149 | 150 | if [ -d $dst ] 151 | then 152 | dst="$dst"/`basename $src` 153 | else 154 | true 155 | fi 156 | fi 157 | 158 | ## this sed command emulates the dirname command 159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 160 | 161 | # Make sure that the destination directory exists. 162 | # this part is taken from Noah Friedman's mkinstalldirs script 163 | 164 | # Skip lots of stat calls in the usual case. 165 | if [ ! -d "$dstdir" ]; then 166 | defaultIFS=' 167 | ' 168 | IFS="${IFS-${defaultIFS}}" 169 | 170 | oIFS="${IFS}" 171 | # Some sh's can't handle IFS=/ for some reason. 172 | IFS='%' 173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 174 | IFS="${oIFS}" 175 | 176 | pathcomp='' 177 | 178 | while [ $# -ne 0 ] ; do 179 | pathcomp="${pathcomp}${1}" 180 | shift 181 | 182 | if [ ! -d "${pathcomp}" ] ; 183 | then 184 | $mkdirprog "${pathcomp}" 185 | else 186 | true 187 | fi 188 | 189 | pathcomp="${pathcomp}/" 190 | done 191 | fi 192 | 193 | if [ x"$dir_arg" != x ] 194 | then 195 | $doit $instcmd $dst && 196 | 197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 201 | else 202 | 203 | # If we're going to rename the final executable, determine the name now. 204 | 205 | if [ x"$transformarg" = x ] 206 | then 207 | dstfile=`basename $dst` 208 | else 209 | dstfile=`basename $dst $transformbasename | 210 | sed $transformarg`$transformbasename 211 | fi 212 | 213 | # don't allow the sed command to completely eliminate the filename 214 | 215 | if [ x"$dstfile" = x ] 216 | then 217 | dstfile=`basename $dst` 218 | else 219 | true 220 | fi 221 | 222 | # Make a temp file name in the proper directory. 223 | 224 | dsttmp=$dstdir/#inst.$$# 225 | 226 | # Move or copy the file name to the temp name 227 | 228 | $doit $instcmd $src $dsttmp && 229 | 230 | trap "rm -f ${dsttmp}" 0 && 231 | 232 | # and set any options; do chmod last to preserve setuid bits 233 | 234 | # If any of these fail, we abort the whole thing. If we want to 235 | # ignore errors from any of these, just make sure not to ignore 236 | # errors from the above "$doit $instcmd $src $dsttmp" command. 237 | 238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 242 | 243 | # Now rename the file to the real destination. 244 | 245 | $doit $rmcmd -f $dstdir/$dstfile && 246 | $doit $mvcmd $dsttmp $dstdir/$dstfile 247 | 248 | fi && 249 | 250 | 251 | exit 0 252 | -------------------------------------------------------------------------------- /simulator.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Homeplug AV INT6x00 simulator device 3 | * 4 | * Copyright (C) 2012, Florian Fainelli 5 | * 6 | * this device mimics the behavior of a Qualcomm/Atheros/Intellon INT6x00 7 | * device and will answer to the frames sent to it 8 | * 9 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 11 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 12 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 13 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 14 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 15 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 16 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 17 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 18 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 19 | * POSSIBILITY OF SUCH DAMAGE. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | #include "homeplug_av.h" 41 | 42 | struct context { 43 | struct event_base *ev; 44 | struct event *read_ev; 45 | int sock_fd; 46 | const char *iface; 47 | int if_index; 48 | }; 49 | 50 | static int sim_send_pkt(struct context *ctx, const uint8_t *to, 51 | const void *hdr, size_t hdrlen, 52 | const void *payload, size_t payload_len) 53 | { 54 | struct sockaddr_ll ll; 55 | struct msghdr msg; 56 | struct iovec iov[3]; 57 | size_t total_len; 58 | uint8_t padding[64]; 59 | int ret; 60 | 61 | memset(&msg, 0, sizeof(msg)); 62 | msg.msg_iov = iov; 63 | total_len = 0; 64 | 65 | iov[msg.msg_iovlen].iov_base = (void *)hdr; 66 | iov[msg.msg_iovlen].iov_len = hdrlen; 67 | total_len += hdrlen; 68 | msg.msg_iovlen = 1; 69 | 70 | if (payload_len) { 71 | iov[msg.msg_iovlen].iov_base = (void *)payload; 72 | iov[msg.msg_iovlen].iov_len = payload_len; 73 | total_len += payload_len; 74 | msg.msg_iovlen++; 75 | } 76 | 77 | if (total_len < 64) { 78 | memset(padding, 0, sizeof(padding)); 79 | iov[msg.msg_iovlen].iov_base = (void *)padding; 80 | iov[msg.msg_iovlen].iov_len = 64 - total_len; 81 | msg.msg_iovlen++; 82 | } 83 | 84 | memset(&ll, 0, sizeof(ll)); 85 | ll.sll_family = AF_PACKET; 86 | ll.sll_ifindex = ctx->if_index; 87 | ll.sll_protocol = htons(ETHERTYPE_HOMEPLUG_AV); 88 | 89 | memcpy(ll.sll_addr, to, ETH_ALEN); 90 | msg.msg_name = ≪ 91 | msg.msg_namelen = sizeof(ll); 92 | 93 | ret = sendmsg(ctx->sock_fd, &msg, 0); 94 | if (ret < 0) { 95 | if (errno != EAGAIN) 96 | perror("sendmsg"); 97 | return ret; 98 | } 99 | 100 | return 0; 101 | } 102 | 103 | struct homeplug_av_vendor_hdr { 104 | uint8_t mmver; 105 | uint16_t mmtype; 106 | uint8_t oui[3]; 107 | } __attribute__((__packed__)); 108 | 109 | static int sim_send_vendor_pkt(struct context *ctx, const uint8_t *to, 110 | uint16_t mmtype, const void *payload, size_t payload_len) 111 | { 112 | struct homeplug_av_vendor_hdr hdr; 113 | 114 | memset(&hdr, 0, sizeof(hdr)); 115 | hdr.mmver = 0; 116 | hdr.mmtype = mmtype; 117 | hdr.oui[0] = 0x00; 118 | hdr.oui[1] = 0xB0; 119 | hdr.oui[2] = 0x52; 120 | 121 | return sim_send_pkt(ctx, to, &hdr, sizeof(hdr), payload, payload_len); 122 | } 123 | 124 | static void sim_read_cb(evutil_socket_t fd, short flags, void *argv) 125 | { 126 | struct context *ctx = argv; 127 | char frame[ETH_DATA_LEN]; 128 | ssize_t len; 129 | socklen_t lllen; 130 | struct sockaddr_ll ll; 131 | struct hpav_frame_header *hdr; 132 | const void *payload = NULL; 133 | size_t payload_size = 0; 134 | uint8_t qca_bcast[ETH_ALEN] = { 0x00, 0xB0, 0x52, 0x00, 0x00, 0x00 }; 135 | int ret; 136 | 137 | 138 | lllen = sizeof(ll); 139 | len = recvfrom(ctx->sock_fd, frame, sizeof(frame), 0, 140 | (struct sockaddr *)&ll, &lllen); 141 | if (len < 0 || len < HPAV_MIN_FRAMSIZ) { 142 | if (errno != EAGAIN) 143 | perror("recvfrom"); 144 | return; 145 | } 146 | 147 | hdr = (struct hpav_frame_header *)frame; 148 | 149 | switch (hdr->mmtype) { 150 | case 0xA000: 151 | fprintf(stdout, "Get Software version\n"); 152 | struct get_device_sw_version_confirm sw_confirm; 153 | 154 | memset(&sw_confirm, 0, sizeof(sw_confirm)); 155 | sw_confirm.mstatus = 0; 156 | sw_confirm.device_id = INT6300_DEVICE_ID; 157 | sw_confirm.version_length = sizeof(sw_confirm.version); 158 | snprintf((char *)sw_confirm.version, sizeof(sw_confirm.version), "%s", "Faifa simulator"); 159 | sw_confirm.upgradeable = 1; 160 | payload = &sw_confirm; 161 | payload_size = sizeof(sw_confirm); 162 | break; 163 | } 164 | 165 | if (!payload_size) 166 | return; 167 | 168 | ret = sim_send_vendor_pkt(ctx, qca_bcast, htole16(hdr->mmtype + 1), 169 | payload, payload_size); 170 | if (ret) 171 | fprintf(stdout, "failed to reply: %d\n", ret); 172 | } 173 | 174 | static int sim_init_ctx(struct context *ctx) 175 | { 176 | int fd; 177 | int ret; 178 | struct sockaddr_ll ll; 179 | 180 | ctx->ev = event_base_new(); 181 | if (!ctx->ev) { 182 | fprintf(stderr, "failed to create new libevent context\n"); 183 | return -ENOMEM; 184 | } 185 | 186 | fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_HOMEPLUG_AV)); 187 | if (fd < 0) { 188 | perror("socket"); 189 | ret = fd; 190 | goto out; 191 | } 192 | 193 | ctx->if_index = if_nametoindex(ctx->iface); 194 | memset(&ll, 0, sizeof(ll)); 195 | ll.sll_family = AF_PACKET; 196 | ll.sll_ifindex = ctx->if_index; 197 | ll.sll_protocol = htons(ETHERTYPE_HOMEPLUG_AV); 198 | 199 | ret = bind(fd, (struct sockaddr *)&ll, sizeof(ll)); 200 | if (ret < 0) { 201 | perror("bind"); 202 | goto out_close; 203 | } 204 | 205 | ctx->sock_fd = fd; 206 | 207 | /* setup libevent for polling this socket */ 208 | ctx->read_ev = event_new(ctx->ev, fd, EV_READ | EV_PERSIST, sim_read_cb, ctx); 209 | if (!ctx->read_ev) { 210 | fprintf(stderr, "failed to create read event"); 211 | ret = -EINVAL; 212 | goto out_close; 213 | } 214 | 215 | fprintf(stdout, "initialized RAW socket\n"); 216 | 217 | event_add(ctx->read_ev, NULL); 218 | 219 | return 0; 220 | 221 | out_close: 222 | close(fd); 223 | out: 224 | event_base_free(ctx->ev); 225 | return ret; 226 | } 227 | 228 | static void sim_deinit_ctx(struct context *ctx) 229 | { 230 | /* disable all events */ 231 | event_base_free(ctx->ev); 232 | } 233 | 234 | static int sim_event_loop(struct context *ctx) 235 | { 236 | event_base_dispatch(ctx->ev); 237 | 238 | return 0; 239 | } 240 | 241 | static void usage(const char *name) 242 | { 243 | fprintf(stderr, "Usage %s [options] [interface]\n" 244 | "-h: this help", 245 | name); 246 | exit(1); 247 | } 248 | 249 | int main(int argc, char **argv) 250 | { 251 | int opt; 252 | struct context ctx; 253 | int ret; 254 | const char *appname = argv[0]; 255 | 256 | memset(&ctx, 0, sizeof(ctx)); 257 | 258 | while ((opt = getopt(argc, argv, "V:h")) > 0) { 259 | switch (opt) { 260 | case 'h': 261 | default: 262 | usage(appname); 263 | break; 264 | } 265 | } 266 | 267 | argv += optind; 268 | argc -= optind; 269 | 270 | ctx.iface = argv[0]; 271 | if (!ctx.iface) 272 | usage(appname); 273 | 274 | ret = sim_init_ctx(&ctx); 275 | if (ret) { 276 | fprintf(stderr, "failed to initialize context\n"); 277 | return ret; 278 | } 279 | 280 | ret = sim_event_loop(&ctx); 281 | 282 | sim_deinit_ctx(&ctx); 283 | return ret; 284 | } 285 | -------------------------------------------------------------------------------- /faifa.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Core library functions 3 | * 4 | * Copyright (C) 2007-2009 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 38 | /* 39 | * In addition, as a special exception, the copyright holders give 40 | * permission to link the code of portions of this program with the 41 | * OpenSSL library under certain conditions as described in each 42 | * individual source file, and distribute linked combinations 43 | * including the two. 44 | * You must obey the GNU General Public License in all respects 45 | * for all of the code used other than OpenSSL. If you modify 46 | * file(s) with this exception, you may extend this exception to your 47 | * version of the file(s), but you are not obligated to do so. If you 48 | * do not wish to do so, delete this exception statement from your 49 | * version. If you delete this exception statement from all source 50 | * files in the program, then also delete it here. 51 | */ 52 | 53 | #include 54 | #ifndef __CYGWIN__ 55 | #include 56 | #endif 57 | 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | 65 | #include "faifa.h" 66 | #include "faifa_compat.h" 67 | #include "faifa_priv.h" 68 | #include "homeplug_av.h" 69 | 70 | void faifa_set_error(faifa_t *faifa, char *format, ...) 71 | { 72 | va_list ap; 73 | 74 | if (!faifa) 75 | return; 76 | 77 | va_start(ap, format); 78 | vsnprintf(faifa->error, sizeof(faifa->error), format, ap); 79 | va_end(ap); 80 | } 81 | 82 | 83 | faifa_t *faifa_init(void) 84 | { 85 | faifa_t *faifa; 86 | 87 | faifa = calloc(1, sizeof(faifa_t)); 88 | if (faifa == NULL) 89 | goto __error_malloc; 90 | 91 | return faifa; 92 | 93 | free(faifa); 94 | __error_malloc: 95 | return NULL; 96 | } 97 | 98 | 99 | void faifa_free(faifa_t *faifa) 100 | { 101 | free(faifa); 102 | } 103 | 104 | 105 | char *faifa_error(faifa_t *faifa) 106 | { 107 | if (faifa) 108 | return faifa->error; 109 | else 110 | return NULL; 111 | } 112 | 113 | 114 | int faifa_open(faifa_t *faifa, char *name) 115 | { 116 | char pcap_errbuf[PCAP_ERRBUF_SIZE]; 117 | int pcap_snaplen = ETHER_MAX_LEN; 118 | 119 | #ifndef __CYGWIN__ 120 | if (getuid() > 0) { 121 | faifa_set_error(faifa, "Must be root to execute this program"); 122 | goto __error_pcap_lookupdev; 123 | } 124 | 125 | if (!pcap_lookupdev(pcap_errbuf)) { 126 | faifa_set_error(faifa, "pcap_lookupdev: can't find device %s", name); 127 | goto __error_pcap_lookupdev; 128 | } 129 | 130 | /* Use open_live on Unixes */ 131 | faifa->pcap = pcap_open_live(name, pcap_snaplen, 1, 100, pcap_errbuf); 132 | #else 133 | pcap_if_t *alldevs; 134 | pcap_if_t *d; 135 | pcap_addr_t *a; 136 | int i = 0; 137 | int inum; 138 | 139 | if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, pcap_errbuf) == -1) { 140 | faifa_set_error(faifa, "Could not get interface list"); 141 | goto __error_pcap_lookupdev; 142 | } 143 | for (d = alldevs; d != NULL; d = d->next) { 144 | if (d->flags & PCAP_IF_LOOPBACK) 145 | continue; 146 | printf("%d. %s", ++i, d->name); 147 | if (d->description) 148 | printf(" (%s)\n", d->description); 149 | else 150 | printf(" No description\n"); 151 | for (a = d->addresses; a; a = a->next) 152 | if (a->addr->sa_family != AF_INET) 153 | continue; 154 | } 155 | 156 | if (!i) { 157 | faifa_set_error(faifa, "No interfaces found"); 158 | goto __error_pcap_lookupdev; 159 | } 160 | __ask_inum: 161 | //TODO : remove this user input to an external function to enumerate interfaces rather then inside a library 162 | printf("Enter interface number (1-%d):", i); 163 | scanf("%d", &inum); 164 | 165 | if (inum < 1 || inum > i) { 166 | printf("Interface index out of range !\n"); 167 | goto __ask_inum; 168 | } 169 | /* Jump to the selected adapter */ 170 | for (d = alldevs, i = 0; i < inum-1; d = d->next, i++); 171 | strcpy(name, d->name); 172 | pcap_snaplen = 65536; 173 | printf("Using: %s\n", name); 174 | 175 | faifa->pcap = pcap_open(name, pcap_snaplen, 1, 1000, NULL, pcap_errbuf); 176 | #endif 177 | if (faifa->pcap == NULL) { 178 | faifa_set_error(faifa, "pcap_open_live: %s", pcap_errbuf); 179 | goto __error_pcap_open_live; 180 | } 181 | 182 | if (pcap_datalink(faifa->pcap) != DLT_EN10MB) { 183 | faifa_set_error(faifa, "pcap: device %s is not Ethernet", name); 184 | goto __error_device_not_ethernet; 185 | } 186 | 187 | /* TODO: Check FreeBSD pcap BIOCIMMEDIATE behavior and compatibility */ 188 | #ifdef DARWIN 189 | u_int arg = 1; 190 | 191 | if (ioctl(pcap_fileno(faifa->pcap), BIOCIMMEDIATE, &arg) < 0) 192 | faifa_set_error(faifa,"Can not set ioctl BIOCIMMEDIATE in %s", name); 193 | #endif 194 | 195 | strncpy(faifa->ifname, name, sizeof(faifa->ifname)); 196 | #ifdef __CYGWIN__ 197 | pcap_freealldevs(alldevs); 198 | #endif 199 | 200 | return 0; 201 | 202 | __error_device_not_ethernet: 203 | pcap_close(faifa->pcap); 204 | __error_pcap_open_live: 205 | __error_pcap_lookupdev: 206 | return -1; 207 | } 208 | 209 | 210 | int faifa_recv(faifa_t *faifa, void *buf, int len) 211 | { 212 | struct pcap_pkthdr *pcap_header; 213 | u_char *pcap_data; 214 | int n; 215 | 216 | n = pcap_next_ex(faifa->pcap, &pcap_header, (const u_char **)&pcap_data); 217 | if (n < 0) { 218 | faifa_set_error(faifa, "pcap_next_ex: %s", pcap_geterr(faifa->pcap)); 219 | return -1; 220 | } 221 | if (n == 0 ) 222 | return 0; 223 | 224 | if ((u_int32_t)len > (u_int32_t)(pcap_header->caplen)) 225 | len = pcap_header->caplen; 226 | 227 | memcpy(buf, pcap_data, len); 228 | 229 | return len; 230 | } 231 | 232 | 233 | int faifa_send(faifa_t *faifa, void *buf, int len) 234 | { 235 | int n; 236 | 237 | n = pcap_sendpacket(faifa->pcap, buf, len); 238 | if (n == -1) { 239 | faifa_set_error(faifa, "pcap_inject: %s", pcap_geterr(faifa->pcap)); 240 | } 241 | 242 | return n; 243 | } 244 | 245 | 246 | typedef struct faifa_loop_data { 247 | faifa_t *faifa; 248 | faifa_loop_handler_t handler; 249 | void *user; 250 | } faifa_loop_data_t; 251 | 252 | void faifa_loop_handler(faifa_loop_data_t *loop_data, struct pcap_pkthdr *pcap_header, void *pcap_data) 253 | { 254 | loop_data->handler(loop_data->faifa, pcap_data, pcap_header->caplen, loop_data->user); 255 | } 256 | 257 | int faifa_loop(faifa_t *faifa, faifa_loop_handler_t handler, void *user) 258 | { 259 | faifa_loop_data_t loop_data = { faifa, handler, user }; 260 | int n; 261 | 262 | n = pcap_loop(faifa->pcap, -1, (void *)faifa_loop_handler, (u_char *)&loop_data); 263 | if (n == -1) { 264 | faifa_set_error(faifa, "pcap_loop: %s", pcap_geterr(faifa->pcap)); 265 | } 266 | 267 | return n; 268 | } 269 | 270 | 271 | int faifa_close(faifa_t *faifa) 272 | { 273 | pcap_close(faifa->pcap); 274 | memset(faifa->ifname, '\0', sizeof(faifa->ifname)); 275 | 276 | return 0; 277 | } 278 | 279 | 280 | int faifa_sprint_hex(char *str, void *buf, int len, char *sep) 281 | { 282 | int avail = len; 283 | u_int8_t *pbuf = buf; 284 | char *pstr = str; 285 | 286 | while (avail > 0) { 287 | pstr += sprintf((char *)pstr, "%02hX%s", (unsigned short int)*pbuf, (avail > 1) ? sep : ""); 288 | pbuf++; 289 | avail--; 290 | } 291 | 292 | return (pstr - str); 293 | } 294 | 295 | 296 | #ifdef __IS_THIS_REALLY_NEEDED__ 297 | 298 | int faifa_get_hwaddr(faifa_t *faifa, u_int8_t *hwaddr) 299 | { 300 | int fd; 301 | struct ifreq ifr; 302 | 303 | fd = socket(AF_INET, SOCK_DRAM, 0); 304 | if (fd == -1) { 305 | faifa_set_error(faifa, "socket: %s", strerror(errno)); 306 | goto __error_socket; 307 | } 308 | 309 | strncpy(ifr.ifr_name, faifa->ifname, sizeof(ifr.ifr_name) - 1); 310 | ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; 311 | 312 | if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { 313 | faifa_set_error(faifa, "ioctl: %s", strerror(errno)); 314 | goto __error_ioctl; 315 | } 316 | memcpy(hwaddr, &(ifr.ifr_hwaddr), ETHER_ADDR_LEN); 317 | 318 | close(fd); 319 | 320 | return 0; 321 | 322 | __error_ioctl: 323 | close(fd); 324 | __error_socket: 325 | return -1; 326 | } 327 | 328 | #endif /* __IS_THIS_REALLY_NEEDED__ */ 329 | 330 | int faifa_parse_mac_addr(faifa_t *faifa, const char *mac, u_int8_t *addr) 331 | { 332 | int i; 333 | long val; 334 | 335 | if (strlen(mac) != 17) { 336 | faifa_set_error(faifa, "macaddr: invalid address length"); 337 | return -1; 338 | } 339 | 340 | if (mac[2] != ':' || mac[5] != ':' || mac[8] != ':' || 341 | mac[11] != ':' || mac[14] != ':') { 342 | faifa_set_error(faifa, "macaddr: invalid format"); 343 | return -1; 344 | } 345 | 346 | for (i = 0; i < ETHER_ADDR_LEN; i++) { 347 | val = strtol(mac + (3 * i), NULL, 16); 348 | addr[i] = val; 349 | } 350 | 351 | return 0; 352 | } 353 | 354 | void faifa_set_dst_addr(faifa_t *faifa, const u_int8_t *addr) 355 | { 356 | memcpy(faifa->dst_addr, addr, ETHER_ADDR_LEN); 357 | } 358 | 359 | void faifa_set_verbose(faifa_t *faifa, int verbose) 360 | { 361 | faifa->verbose = verbose; 362 | } 363 | -------------------------------------------------------------------------------- /hpav_cfg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Lightweight Homeplug AV configuration utility 3 | * 4 | * Generates a NMK/DAK given their NPW and DPW 5 | * 6 | * Copyright (C) 2012, Florian Fainelli 7 | * Copyright (C) 2014, Xavier Carcelle 8 | * 9 | * The BSD License 10 | * =============== 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in 19 | * the documentation and/or other materials provided with the 20 | * distribution. 21 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 22 | * contributors may be used to endorse or promote products derived 23 | * from this software without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 29 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "homeplug_av.h" 57 | #include "crypto.h" 58 | 59 | struct context { 60 | int sock_fd; 61 | int if_index; 62 | }; 63 | 64 | static int send_pkt(struct context *ctx, const uint8_t *to, 65 | const void *hdr, size_t hdrlen, 66 | const void *payload, size_t payload_len) 67 | { 68 | struct sockaddr_ll ll; 69 | struct msghdr msg; 70 | struct iovec iov[3]; 71 | size_t total_len; 72 | uint8_t padding[64]; 73 | int ret; 74 | 75 | memset(&msg, 0, sizeof(msg)); 76 | msg.msg_iov = iov; 77 | total_len = 0; 78 | 79 | iov[msg.msg_iovlen].iov_base = (void *)hdr; 80 | iov[msg.msg_iovlen].iov_len = hdrlen; 81 | total_len += hdrlen; 82 | msg.msg_iovlen = 1; 83 | 84 | if (payload_len) { 85 | iov[msg.msg_iovlen].iov_base = (void *)payload; 86 | iov[msg.msg_iovlen].iov_len = payload_len; 87 | total_len += payload_len; 88 | msg.msg_iovlen++; 89 | } 90 | 91 | if (total_len < 64) { 92 | memset(padding, 0, sizeof(padding)); 93 | iov[msg.msg_iovlen].iov_base = (void *)padding; 94 | iov[msg.msg_iovlen].iov_len = 64 - total_len; 95 | msg.msg_iovlen++; 96 | } 97 | 98 | memset(&ll, 0, sizeof(ll)); 99 | ll.sll_family = AF_PACKET; 100 | ll.sll_ifindex = ctx->if_index; 101 | ll.sll_protocol = htons(ETHERTYPE_HOMEPLUG_AV); 102 | 103 | memcpy(ll.sll_addr, to, ETH_ALEN); 104 | msg.msg_name = ≪ 105 | msg.msg_namelen = sizeof(ll); 106 | 107 | ret = sendmsg(ctx->sock_fd, &msg, 0); 108 | if (ret < 0) { 109 | if (errno != EAGAIN) 110 | perror("sendmsg"); 111 | return ret; 112 | } 113 | 114 | return 0; 115 | } 116 | 117 | struct homeplug_av_vendor_hdr { 118 | uint8_t mmver; 119 | uint16_t mmtype; 120 | uint8_t oui[3]; 121 | } __attribute__((__packed__)); 122 | 123 | static int send_vendor_pkt(struct context *ctx, const uint8_t *to, 124 | uint16_t mmtype, const void *payload, size_t payload_len) 125 | { 126 | struct homeplug_av_vendor_hdr hdr; 127 | 128 | memset(&hdr, 0, sizeof(hdr)); 129 | hdr.mmver = 0; 130 | hdr.mmtype = mmtype; 131 | hdr.oui[0] = 0x00; 132 | hdr.oui[1] = 0xB0; 133 | hdr.oui[2] = 0x52; 134 | 135 | return send_pkt(ctx, to, &hdr, sizeof(hdr), payload, payload_len); 136 | } 137 | 138 | static int init_socket(struct context *ctx, const char *iface) 139 | { 140 | int ret; 141 | struct sockaddr_ll ll; 142 | 143 | ctx->sock_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETHERTYPE_HOMEPLUG_AV)); 144 | if (ctx->sock_fd < 0) { 145 | perror("socket"); 146 | return -1; 147 | } 148 | 149 | ctx->if_index = if_nametoindex(iface); 150 | memset(&ll, 0, sizeof(ll)); 151 | ll.sll_family = AF_PACKET; 152 | ll.sll_ifindex = ctx->if_index; 153 | ll.sll_protocol = htons(ETHERTYPE_HOMEPLUG_AV); 154 | 155 | ret = bind(ctx->sock_fd, (struct sockaddr *)&ll, sizeof(ll)); 156 | if (ret < 0) { 157 | perror("bind"); 158 | goto out_close; 159 | } 160 | 161 | return 0; 162 | 163 | out_close: 164 | close(ctx->sock_fd); 165 | return ret; 166 | } 167 | 168 | static uint8_t bcast_hpav_mac[ETH_ALEN] = { 0x00, 0xB0, 0x52, 0x00, 0x00, 0x01 }; 169 | 170 | static int send_key(struct context *ctx, const char *npw, 171 | const char *dpw, const uint8_t mac[ETH_ALEN]) 172 | { 173 | struct set_encryption_key_request key_req; 174 | uint8_t key[16]; 175 | 176 | memset(&key_req, 0, sizeof(key_req)); 177 | 178 | key_req.peks = 0x01; 179 | 180 | gen_passphrase(npw, key, nmk_salt); 181 | memcpy(key_req.nmk, key, AES_KEY_SIZE); 182 | key_req.peks_payload = NO_KEY; 183 | 184 | if (dpw) { 185 | gen_passphrase(dpw, key, dak_salt); 186 | memcpy(key_req.dak, key, AES_KEY_SIZE); 187 | key_req.peks_payload = DST_STA_DAK; 188 | } 189 | 190 | memcpy(key_req.rdra, mac, ETH_ALEN); 191 | 192 | return send_vendor_pkt(ctx, mac, HPAV_MMTYPE_SET_KEY_REQ, 193 | &key_req, sizeof(key_req)); 194 | 195 | } 196 | 197 | 198 | 199 | 200 | static int read_key_confirm(struct context *ctx, const uint8_t mac[ETH_ALEN]) 201 | { 202 | uint8_t frame[ETH_DATA_LEN]; 203 | ssize_t len; 204 | socklen_t sk_len; 205 | struct sockaddr_ll ll; 206 | struct hpav_frame *hpav_frame; 207 | uint8_t status; 208 | uint8_t *from; 209 | 210 | sk_len = sizeof(ll); 211 | len = recvfrom(ctx->sock_fd, frame, sizeof(frame), 0, 212 | (struct sockaddr *)&ll, &sk_len); 213 | if (len < 0 || len < HPAV_MIN_FRAMSIZ) { 214 | if (errno != EAGAIN) 215 | perror("recvfrom"); 216 | return len; 217 | } 218 | 219 | from = ll.sll_addr; 220 | 221 | /* destination MAC is different from broadcast HomePlug AV MAC 222 | * and source MAC is different form destination MAC 223 | */ 224 | if (memcmp(mac, bcast_hpav_mac, ETH_ALEN) && 225 | memcmp(mac, from, ETH_ALEN)) { 226 | fprintf(stderr, "spurious reply from another station\n"); 227 | return 1; 228 | } 229 | 230 | hpav_frame = (struct hpav_frame *)frame; 231 | if (le16toh(hpav_frame->header.mmtype) != HPAV_MMTYPE_SET_KEY_CNF) 232 | return 1; 233 | 234 | status = hpav_frame->payload.vendor.data[0]; 235 | switch (status) { 236 | case KEY_SUCCESS: 237 | fprintf(stdout, "Success!!\n"); 238 | return 0; 239 | case KEY_INV_EKS: 240 | fprintf(stderr, "Invalid EKS\n"); 241 | return 1; 242 | case KEY_INV_PKS: 243 | fprintf(stderr, "Invalid PKS\n"); 244 | return 1; 245 | default: 246 | fprintf(stderr, "unknown answer: 0x%02x\n", status); 247 | } 248 | 249 | return 0; 250 | } 251 | 252 | 253 | 254 | static int pushbutton_request(struct context *ctx, uint8_t *mac) 255 | { 256 | return send_vendor_pkt(ctx, mac, HPAV_MMTYPE_MS_PB_ENC, 257 | NULL, 0); 258 | } 259 | 260 | 261 | static int send_reset(struct context *ctx, uint8_t *mac) 262 | { 263 | return send_vendor_pkt(ctx, mac, HPAV_MMTYPE_RS_DEV_REQ, 264 | NULL, 0); 265 | } 266 | 267 | static int generate_passphrase(struct context *ctx, 268 | const char *npw, const char *dpw) 269 | { 270 | uint8_t key[16]; 271 | int i; 272 | 273 | if (!npw && !dpw) { 274 | fprintf(stderr, "missing NPW and DPW\n"); 275 | return 1; 276 | } 277 | 278 | if (npw) 279 | gen_passphrase(npw, key, nmk_salt); 280 | else 281 | gen_passphrase(dpw, key, dak_salt); 282 | 283 | for (i = 0; i < sizeof(key); i++) 284 | fprintf(stdout, "%02x", key[i]); 285 | 286 | return 0; 287 | } 288 | 289 | static void sighandler(int signo) 290 | { 291 | if (signo == SIGALRM) { 292 | fprintf(stdout, "timeout reading answer from sta, exiting\n"); 293 | exit(1); 294 | } 295 | } 296 | 297 | static void usage(void) 298 | { 299 | fprintf(stderr, "Usage: hpav_cfg [options] interface\n" 300 | "-n: NPW passphrase\n" 301 | "-d: DPW passphrase\n" 302 | "-p: same as -n (deprecated)\n" 303 | "-a: device MAC address\n" 304 | "-r: send a device reset\n" 305 | "-u: PusbButton request\n" 306 | "-k: hash only\n"); 307 | } 308 | 309 | int main(int argc, char **argv) 310 | { 311 | int opt; 312 | int ret; 313 | const char *mac_address = NULL; 314 | const char *npw = NULL; 315 | const char *dpw = NULL; 316 | const char *iface = NULL; 317 | struct context ctx; 318 | unsigned int hash_only = 0; 319 | unsigned int reset_device = 0; 320 | unsigned int push_button = 0; 321 | uint8_t mac[ETH_ALEN] = { 0 }; 322 | 323 | memset(&ctx, 0, sizeof(ctx)); 324 | 325 | while ((opt = getopt(argc, argv, "n:d:p:a:i:ukrh")) > 0) { 326 | switch (opt) { 327 | case 'n': 328 | case 'p': 329 | npw = optarg; 330 | break; 331 | case 'd': 332 | dpw = optarg; 333 | break; 334 | case 'a': 335 | mac_address = optarg; 336 | break; 337 | case 'i': 338 | iface = optarg; 339 | break; 340 | case 'k': 341 | hash_only = 1; 342 | break; 343 | case 'r': 344 | reset_device = 1; 345 | break; 346 | case 'u': 347 | push_button = 1; 348 | break; 349 | case 'h': 350 | default: 351 | usage(); 352 | return 1; 353 | } 354 | } 355 | 356 | if (argc < 2) { 357 | usage(); 358 | return 1; 359 | } 360 | 361 | argc -= optind; 362 | argv += optind; 363 | 364 | if (hash_only) 365 | return generate_passphrase(&ctx, npw, dpw); 366 | 367 | iface = argv[0]; 368 | if (!iface) { 369 | fprintf(stderr, "missing interface argument\n"); 370 | return 1; 371 | } 372 | 373 | 374 | fprintf(stdout, "Interface: %s\n", iface); 375 | 376 | if (mac_address) { 377 | ret = sscanf(mac_address, 378 | "%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8":%"SCNx8"", 379 | &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); 380 | if (ret != ETH_ALEN) { 381 | fprintf(stdout, "invalid MAC address\n"); 382 | return ret; 383 | } 384 | fprintf(stdout, "MAC: %s\n", mac_address); 385 | } else { 386 | memcpy(mac, bcast_hpav_mac, sizeof(bcast_hpav_mac)); 387 | fprintf(stdout, "MAC: using broadcast HPAV\n"); 388 | } 389 | 390 | ret = init_socket(&ctx, iface); 391 | if (ret) { 392 | fprintf(stdout, "failed to initialize raw socket\n"); 393 | return ret; 394 | } 395 | 396 | if (reset_device) { 397 | ret = send_reset(&ctx, mac); 398 | if (ret) 399 | fprintf(stdout, "failed to send reset\n"); 400 | 401 | return ret; 402 | } 403 | 404 | 405 | if (push_button) { 406 | ret = pushbutton_request(&ctx, mac); 407 | fprintf(stdout, "sending PushButton request on the local link\n"); 408 | if (ret) 409 | fprintf(stdout, "failed to send push_button\n"); 410 | return ret; 411 | } 412 | 413 | 414 | if (!npw) { 415 | fprintf(stderr, "missing NPW argument\n"); 416 | return 1; 417 | } 418 | 419 | fprintf(stdout, "NPW: %s\n", npw); 420 | ret = send_key(&ctx, npw, dpw, mac); 421 | if (ret) { 422 | fprintf(stdout, "failed to send key\n"); 423 | return ret; 424 | } 425 | 426 | if (signal(SIGALRM, sighandler) == SIG_ERR) { 427 | fprintf(stdout, "failed to setup signal handler\n"); 428 | return ret; 429 | } 430 | 431 | /* catch answer or timeout */ 432 | alarm(3); 433 | 434 | ret = read_key_confirm(&ctx, mac); 435 | 436 | return ret; 437 | } 438 | -------------------------------------------------------------------------------- /sha2.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sha2.c,v 1.6 2004/05/03 02:57:36 millert Exp $ */ 2 | 3 | /* 4 | * FILE: sha2.c 5 | * AUTHOR: Aaron D. Gifford 6 | * 7 | * Copyright (c) 2000-2001, Aaron D. Gifford 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the copyright holder nor the names of contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ 35 | * 36 | * $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.8 2006/10/04 00:29:46 momjian Exp $ 37 | */ 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "endian.h" 44 | #include "sha2.h" 45 | 46 | /* 47 | * UNROLLED TRANSFORM LOOP NOTE: 48 | * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 49 | * loop version for the hash transform rounds (defined using macros 50 | * later in this file). Either define on the command line, for example: 51 | * 52 | * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 53 | * 54 | * or define below: 55 | * 56 | * #define SHA2_UNROLL_TRANSFORM 57 | * 58 | */ 59 | 60 | 61 | /*** SHA-256/384/512 Machine Architecture Definitions *****************/ 62 | /* 63 | * BYTE_ORDER NOTE: 64 | * 65 | * Please make sure that your system defines BYTE_ORDER. If your 66 | * architecture is little-endian, make sure it also defines 67 | * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 68 | * equivilent. 69 | * 70 | * If your system does not define the above, then you can do so by 71 | * hand like this: 72 | * 73 | * #define LITTLE_ENDIAN 1234 74 | * #define BIG_ENDIAN 4321 75 | * 76 | * And for little-endian machines, add: 77 | * 78 | * #define BYTE_ORDER LITTLE_ENDIAN 79 | * 80 | * Or for big-endian machines: 81 | * 82 | * #define BYTE_ORDER BIG_ENDIAN 83 | * 84 | * The FreeBSD machine this was written on defines BYTE_ORDER 85 | * appropriately by including (which in turn includes 86 | * where the appropriate definitions are actually 87 | * made). 88 | */ 89 | #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 90 | #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 91 | #endif 92 | 93 | 94 | /*** SHA-256/384/512 Various Length Definitions ***********************/ 95 | /* NOTE: Most of these are in sha2.h */ 96 | #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) 97 | #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) 98 | 99 | 100 | /*** ENDIAN REVERSAL MACROS *******************************************/ 101 | #if BYTE_ORDER == LITTLE_ENDIAN 102 | #define REVERSE32(w,x) { \ 103 | uint32_t tmp = (w); \ 104 | tmp = (tmp >> 16) | (tmp << 16); \ 105 | (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ 106 | } 107 | #define REVERSE64(w,x) { \ 108 | uint64_t tmp = (w); \ 109 | tmp = (tmp >> 32) | (tmp << 32); \ 110 | tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ 111 | ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ 112 | (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ 113 | ((tmp & 0x0000ffff0000ffffULL) << 16); \ 114 | } 115 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 116 | 117 | /* 118 | * Macro for incrementally adding the unsigned 64-bit integer n to the 119 | * unsigned 128-bit integer (represented using a two-element array of 120 | * 64-bit words): 121 | */ 122 | #define ADDINC128(w,n) { \ 123 | (w)[0] += (uint64_t)(n); \ 124 | if ((w)[0] < (n)) { \ 125 | (w)[1]++; \ 126 | } \ 127 | } 128 | 129 | /*** THE SIX LOGICAL FUNCTIONS ****************************************/ 130 | /* 131 | * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 132 | * 133 | * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 134 | * S is a ROTATION) because the SHA-256/384/512 description document 135 | * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 136 | * same "backwards" definition. 137 | */ 138 | /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ 139 | #define R(b,x) ((x) >> (b)) 140 | /* 32-bit Rotate-right (used in SHA-256): */ 141 | #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) 142 | 143 | /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ 144 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 145 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 146 | 147 | /* Four of six logical functions used in SHA-256: */ 148 | #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 149 | #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 150 | #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) 151 | #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 152 | 153 | /* Four of six logical functions used in SHA-384 and SHA-512: */ 154 | #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 155 | #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 156 | #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) 157 | #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) 158 | 159 | /*** INTERNAL FUNCTION PROTOTYPES *************************************/ 160 | /* NOTE: These should not be accessed directly from outside this 161 | * library -- they are intended for private internal visibility/use 162 | * only. 163 | */ 164 | static void SHA256_Transform(SHA256_CTX *, const uint8_t *); 165 | 166 | 167 | /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 168 | /* Hash constant words K for SHA-256: */ 169 | static const uint32_t K256[64] = { 170 | 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 171 | 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 172 | 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 173 | 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 174 | 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 175 | 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 176 | 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 177 | 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 178 | 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 179 | 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 180 | 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 181 | 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 182 | 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 183 | 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 184 | 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 185 | 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 186 | }; 187 | 188 | /* Initial hash value H for SHA-256: */ 189 | static const uint32_t sha256_initial_hash_value[8] = { 190 | 0x6a09e667UL, 191 | 0xbb67ae85UL, 192 | 0x3c6ef372UL, 193 | 0xa54ff53aUL, 194 | 0x510e527fUL, 195 | 0x9b05688cUL, 196 | 0x1f83d9abUL, 197 | 0x5be0cd19UL 198 | }; 199 | 200 | /*** SHA-256: *********************************************************/ 201 | void 202 | SHA256_Init(SHA256_CTX * context) 203 | { 204 | if (context == NULL) 205 | return; 206 | memcpy(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); 207 | memset(context->buffer, 0, SHA256_BLOCK_LENGTH); 208 | context->bitcount = 0; 209 | } 210 | 211 | #ifdef SHA2_UNROLL_TRANSFORM 212 | 213 | /* Unrolled SHA-256 round macros: */ 214 | 215 | #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \ 216 | W256[j] = (uint32_t)data[3] | ((uint32)data[2] << 8) | \ 217 | ((uint32_t)data[1] << 16) | ((uint32)data[0] << 24); \ 218 | data += 4; \ 219 | T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ 220 | (d) += T1; \ 221 | (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ 222 | j++; \ 223 | } while(0) 224 | 225 | #define ROUND256(a,b,c,d,e,f,g,h) do { \ 226 | s0 = W256[(j+1)&0x0f]; \ 227 | s0 = sigma0_256(s0); \ 228 | s1 = W256[(j+14)&0x0f]; \ 229 | s1 = sigma1_256(s1); \ 230 | T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \ 231 | (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ 232 | (d) += T1; \ 233 | (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ 234 | j++; \ 235 | } while(0) 236 | 237 | static void 238 | SHA256_Transform(SHA256_CTX * context, const uint8_t *data) 239 | { 240 | uint32_t a, 241 | b, 242 | c, 243 | d, 244 | e, 245 | f, 246 | g, 247 | h, 248 | s0, 249 | s1; 250 | uint32_t T1, 251 | *W256; 252 | int j; 253 | 254 | W256 = (uint32_t *) context->buffer; 255 | 256 | /* Initialize registers with the prev. intermediate value */ 257 | a = context->state[0]; 258 | b = context->state[1]; 259 | c = context->state[2]; 260 | d = context->state[3]; 261 | e = context->state[4]; 262 | f = context->state[5]; 263 | g = context->state[6]; 264 | h = context->state[7]; 265 | 266 | j = 0; 267 | do 268 | { 269 | /* Rounds 0 to 15 (unrolled): */ 270 | ROUND256_0_TO_15(a, b, c, d, e, f, g, h); 271 | ROUND256_0_TO_15(h, a, b, c, d, e, f, g); 272 | ROUND256_0_TO_15(g, h, a, b, c, d, e, f); 273 | ROUND256_0_TO_15(f, g, h, a, b, c, d, e); 274 | ROUND256_0_TO_15(e, f, g, h, a, b, c, d); 275 | ROUND256_0_TO_15(d, e, f, g, h, a, b, c); 276 | ROUND256_0_TO_15(c, d, e, f, g, h, a, b); 277 | ROUND256_0_TO_15(b, c, d, e, f, g, h, a); 278 | } while (j < 16); 279 | 280 | /* Now for the remaining rounds to 64: */ 281 | do 282 | { 283 | ROUND256(a, b, c, d, e, f, g, h); 284 | ROUND256(h, a, b, c, d, e, f, g); 285 | ROUND256(g, h, a, b, c, d, e, f); 286 | ROUND256(f, g, h, a, b, c, d, e); 287 | ROUND256(e, f, g, h, a, b, c, d); 288 | ROUND256(d, e, f, g, h, a, b, c); 289 | ROUND256(c, d, e, f, g, h, a, b); 290 | ROUND256(b, c, d, e, f, g, h, a); 291 | } while (j < 64); 292 | 293 | /* Compute the current intermediate hash value */ 294 | context->state[0] += a; 295 | context->state[1] += b; 296 | context->state[2] += c; 297 | context->state[3] += d; 298 | context->state[4] += e; 299 | context->state[5] += f; 300 | context->state[6] += g; 301 | context->state[7] += h; 302 | 303 | /* Clean up */ 304 | a = b = c = d = e = f = g = h = T1 = 0; 305 | } 306 | #else /* SHA2_UNROLL_TRANSFORM */ 307 | 308 | static void 309 | SHA256_Transform(SHA256_CTX * context, const uint8_t *data) 310 | { 311 | uint32_t a, 312 | b, 313 | c, 314 | d, 315 | e, 316 | f, 317 | g, 318 | h, 319 | s0, 320 | s1; 321 | uint32_t T1, 322 | T2, 323 | *W256; 324 | int j; 325 | 326 | W256 = (uint32_t *) context->buffer; 327 | 328 | /* Initialize registers with the prev. intermediate value */ 329 | a = context->state[0]; 330 | b = context->state[1]; 331 | c = context->state[2]; 332 | d = context->state[3]; 333 | e = context->state[4]; 334 | f = context->state[5]; 335 | g = context->state[6]; 336 | h = context->state[7]; 337 | 338 | j = 0; 339 | do 340 | { 341 | W256[j] = (uint32_t) data[3] | ((uint32_t) data[2] << 8) | 342 | ((uint32_t) data[1] << 16) | ((uint32_t) data[0] << 24); 343 | data += 4; 344 | /* Apply the SHA-256 compression function to update a..h */ 345 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 346 | T2 = Sigma0_256(a) + Maj(a, b, c); 347 | h = g; 348 | g = f; 349 | f = e; 350 | e = d + T1; 351 | d = c; 352 | c = b; 353 | b = a; 354 | a = T1 + T2; 355 | 356 | j++; 357 | } while (j < 16); 358 | 359 | do 360 | { 361 | /* Part of the message block expansion: */ 362 | s0 = W256[(j + 1) & 0x0f]; 363 | s0 = sigma0_256(s0); 364 | s1 = W256[(j + 14) & 0x0f]; 365 | s1 = sigma1_256(s1); 366 | 367 | /* Apply the SHA-256 compression function to update a..h */ 368 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 369 | (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0); 370 | T2 = Sigma0_256(a) + Maj(a, b, c); 371 | h = g; 372 | g = f; 373 | f = e; 374 | e = d + T1; 375 | d = c; 376 | c = b; 377 | b = a; 378 | a = T1 + T2; 379 | 380 | j++; 381 | } while (j < 64); 382 | 383 | /* Compute the current intermediate hash value */ 384 | context->state[0] += a; 385 | context->state[1] += b; 386 | context->state[2] += c; 387 | context->state[3] += d; 388 | context->state[4] += e; 389 | context->state[5] += f; 390 | context->state[6] += g; 391 | context->state[7] += h; 392 | 393 | /* Clean up */ 394 | a = b = c = d = e = f = g = h = T1 = T2 = 0; 395 | } 396 | #endif /* SHA2_UNROLL_TRANSFORM */ 397 | 398 | void 399 | SHA256_Update(SHA256_CTX * context, const uint8_t *data, size_t len) 400 | { 401 | size_t freespace, 402 | usedspace; 403 | 404 | /* Calling with no data is valid (we do nothing) */ 405 | if (len == 0) 406 | return; 407 | 408 | usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 409 | if (usedspace > 0) 410 | { 411 | /* Calculate how much free space is available in the buffer */ 412 | freespace = SHA256_BLOCK_LENGTH - usedspace; 413 | 414 | if (len >= freespace) 415 | { 416 | /* Fill the buffer completely and process it */ 417 | memcpy(&context->buffer[usedspace], data, freespace); 418 | context->bitcount += freespace << 3; 419 | len -= freespace; 420 | data += freespace; 421 | SHA256_Transform(context, context->buffer); 422 | } 423 | else 424 | { 425 | /* The buffer is not yet full */ 426 | memcpy(&context->buffer[usedspace], data, len); 427 | context->bitcount += len << 3; 428 | /* Clean up: */ 429 | usedspace = freespace = 0; 430 | return; 431 | } 432 | } 433 | while (len >= SHA256_BLOCK_LENGTH) 434 | { 435 | /* Process as many complete blocks as we can */ 436 | SHA256_Transform(context, data); 437 | context->bitcount += SHA256_BLOCK_LENGTH << 3; 438 | len -= SHA256_BLOCK_LENGTH; 439 | data += SHA256_BLOCK_LENGTH; 440 | } 441 | if (len > 0) 442 | { 443 | /* There's left-overs, so save 'em */ 444 | memcpy(context->buffer, data, len); 445 | context->bitcount += len << 3; 446 | } 447 | /* Clean up: */ 448 | usedspace = freespace = 0; 449 | } 450 | 451 | static void 452 | SHA256_Last(SHA256_CTX * context) 453 | { 454 | unsigned int usedspace; 455 | 456 | usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 457 | #if BYTE_ORDER == LITTLE_ENDIAN 458 | /* Convert FROM host byte order */ 459 | REVERSE64(context->bitcount, context->bitcount); 460 | #endif 461 | if (usedspace > 0) 462 | { 463 | /* Begin padding with a 1 bit: */ 464 | context->buffer[usedspace++] = 0x80; 465 | 466 | if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) 467 | { 468 | /* Set-up for the last transform: */ 469 | memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace); 470 | } 471 | else 472 | { 473 | if (usedspace < SHA256_BLOCK_LENGTH) 474 | { 475 | memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace); 476 | } 477 | /* Do second-to-last transform: */ 478 | SHA256_Transform(context, context->buffer); 479 | 480 | /* And set-up for the last transform: */ 481 | memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); 482 | } 483 | } 484 | else 485 | { 486 | /* Set-up for the last transform: */ 487 | memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); 488 | 489 | /* Begin padding with a 1 bit: */ 490 | *context->buffer = 0x80; 491 | } 492 | /* Set the bit count: */ 493 | *(uint64_t *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; 494 | 495 | /* Final transform: */ 496 | SHA256_Transform(context, context->buffer); 497 | } 498 | 499 | void 500 | SHA256_Final(uint8_t digest[], SHA256_CTX * context) 501 | { 502 | /* If no digest buffer is passed, we don't bother doing this: */ 503 | if (digest != NULL) 504 | { 505 | SHA256_Last(context); 506 | 507 | #if BYTE_ORDER == LITTLE_ENDIAN 508 | { 509 | /* Convert TO host byte order */ 510 | int j; 511 | 512 | for (j = 0; j < 8; j++) 513 | { 514 | REVERSE32(context->state[j], context->state[j]); 515 | } 516 | } 517 | #endif 518 | memcpy(digest, context->state, SHA256_DIGEST_LENGTH); 519 | } 520 | 521 | /* Clean up state data: */ 522 | memset(context, 0, sizeof(*context)); 523 | } 524 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | ---------------------------------------- 2 | 3 | GNU GENERAL PUBLIC LICENSE 4 | Version 2, June 1991 5 | 6 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 7 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 8 | Everyone is permitted to copy and distribute verbatim copies 9 | of this license document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your 14 | freedom to share and change it. By contrast, the GNU General Public 15 | License is intended to guarantee your freedom to share and change free 16 | software--to make sure the software is free for all its users. This 17 | General Public License applies to most of the Free Software 18 | Foundation's software and to any other program whose authors commit to 19 | using it. (Some other Free Software Foundation software is covered by 20 | the GNU Library General Public License instead.) You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not 24 | price. Our General Public Licenses are designed to make sure that you 25 | have the freedom to distribute copies of free software (and charge for 26 | this service if you wish), that you receive source code or can get it 27 | if you want it, that you can change the software or use pieces of it 28 | in new free programs; and that you know you can do these things. 29 | 30 | To protect your rights, we need to make restrictions that forbid 31 | anyone to deny you these rights or to ask you to surrender the rights. 32 | These restrictions translate to certain responsibilities for you if you 33 | distribute copies of the software, or if you modify it. 34 | 35 | For example, if you distribute copies of such a program, whether 36 | gratis or for a fee, you must give the recipients all the rights that 37 | you have. You must make sure that they, too, receive or can get the 38 | source code. And you must show them these terms so they know their 39 | rights. 40 | 41 | We protect your rights with two steps: (1) copyright the software, and 42 | (2) offer you this license which gives you legal permission to copy, 43 | distribute and/or modify the software. 44 | 45 | Also, for each author's protection and ours, we want to make certain 46 | that everyone understands that there is no warranty for this free 47 | software. If the software is modified by someone else and passed on, we 48 | want its recipients to know that what they have is not the original, so 49 | that any problems introduced by others will not reflect on the original 50 | authors' reputations. 51 | 52 | Finally, any free program is threatened constantly by software 53 | patents. We wish to avoid the danger that redistributors of a free 54 | program will individually obtain patent licenses, in effect making the 55 | program proprietary. To prevent this, we have made it clear that any 56 | patent must be licensed for everyone's free use or not licensed at all. 57 | 58 | The precise terms and conditions for copying, distribution and 59 | modification follow. 60 | 61 | GNU GENERAL PUBLIC LICENSE 62 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 63 | 64 | 0. This License applies to any program or other work which contains 65 | a notice placed by the copyright holder saying it may be distributed 66 | under the terms of this General Public License. The "Program", below, 67 | refers to any such program or work, and a "work based on the Program" 68 | means either the Program or any derivative work under copyright law: 69 | that is to say, a work containing the Program or a portion of it, 70 | either verbatim or with modifications and/or translated into another 71 | language. (Hereinafter, translation is included without limitation in 72 | the term "modification".) Each licensee is addressed as "you". 73 | 74 | Activities other than copying, distribution and modification are not 75 | covered by this License; they are outside its scope. The act of 76 | running the Program is not restricted, and the output from the Program 77 | is covered only if its contents constitute a work based on the 78 | Program (independent of having been made by running the Program). 79 | Whether that is true depends on what the Program does. 80 | 81 | 1. You may copy and distribute verbatim copies of the Program's 82 | source code as you receive it, in any medium, provided that you 83 | conspicuously and appropriately publish on each copy an appropriate 84 | copyright notice and disclaimer of warranty; keep intact all the 85 | notices that refer to this License and to the absence of any warranty; 86 | and give any other recipients of the Program a copy of this License 87 | along with the Program. 88 | 89 | You may charge a fee for the physical act of transferring a copy, and 90 | you may at your option offer warranty protection in exchange for a fee. 91 | 92 | 2. You may modify your copy or copies of the Program or any portion 93 | of it, thus forming a work based on the Program, and copy and 94 | distribute such modifications or work under the terms of Section 1 95 | above, provided that you also meet all of these conditions: 96 | 97 | a) You must cause the modified files to carry prominent notices 98 | stating that you changed the files and the date of any change. 99 | 100 | b) You must cause any work that you distribute or publish, that in 101 | whole or in part contains or is derived from the Program or any 102 | part thereof, to be licensed as a whole at no charge to all third 103 | parties under the terms of this License. 104 | 105 | c) If the modified program normally reads commands interactively 106 | when run, you must cause it, when started running for such 107 | interactive use in the most ordinary way, to print or display an 108 | announcement including an appropriate copyright notice and a 109 | notice that there is no warranty (or else, saying that you provide 110 | a warranty) and that users may redistribute the program under 111 | these conditions, and telling the user how to view a copy of this 112 | License. (Exception: if the Program itself is interactive but 113 | does not normally print such an announcement, your work based on 114 | the Program is not required to print an announcement.) 115 | 116 | These requirements apply to the modified work as a whole. If 117 | identifiable sections of that work are not derived from the Program, 118 | and can be reasonably considered independent and separate works in 119 | themselves, then this License, and its terms, do not apply to those 120 | sections when you distribute them as separate works. But when you 121 | distribute the same sections as part of a whole which is a work based 122 | on the Program, the distribution of the whole must be on the terms of 123 | this License, whose permissions for other licensees extend to the 124 | entire whole, and thus to each and every part regardless of who wrote it. 125 | 126 | Thus, it is not the intent of this section to claim rights or contest 127 | your rights to work written entirely by you; rather, the intent is to 128 | exercise the right to control the distribution of derivative or 129 | collective works based on the Program. 130 | 131 | In addition, mere aggregation of another work not based on the Program 132 | with the Program (or with a work based on the Program) on a volume of 133 | a storage or distribution medium does not bring the other work under 134 | the scope of this License. 135 | 136 | 3. You may copy and distribute the Program (or a work based on it, 137 | under Section 2) in object code or executable form under the terms of 138 | Sections 1 and 2 above provided that you also do one of the following: 139 | 140 | a) Accompany it with the complete corresponding machine-readable 141 | source code, which must be distributed under the terms of Sections 142 | 1 and 2 above on a medium customarily used for software interchange; or, 143 | 144 | b) Accompany it with a written offer, valid for at least three 145 | years, to give any third party, for a charge no more than your 146 | cost of physically performing source distribution, a complete 147 | machine-readable copy of the corresponding source code, to be 148 | distributed under the terms of Sections 1 and 2 above on a medium 149 | customarily used for software interchange; or, 150 | 151 | c) Accompany it with the information you received as to the offer 152 | to distribute corresponding source code. (This alternative is 153 | allowed only for noncommercial distribution and only if you 154 | received the program in object code or executable form with such 155 | an offer, in accord with Subsection b above.) 156 | 157 | The source code for a work means the preferred form of the work for 158 | making modifications to it. For an executable work, complete source 159 | code means all the source code for all modules it contains, plus any 160 | associated interface definition files, plus the scripts used to 161 | control compilation and installation of the executable. However, as a 162 | special exception, the source code distributed need not include 163 | anything that is normally distributed (in either source or binary 164 | form) with the major components (compiler, kernel, and so on) of the 165 | operating system on which the executable runs, unless that component 166 | itself accompanies the executable. 167 | 168 | If distribution of executable or object code is made by offering 169 | access to copy from a designated place, then offering equivalent 170 | access to copy the source code from the same place counts as 171 | distribution of the source code, even though third parties are not 172 | compelled to copy the source along with the object code. 173 | 174 | 4. You may not copy, modify, sublicense, or distribute the Program 175 | except as expressly provided under this License. Any attempt 176 | otherwise to copy, modify, sublicense or distribute the Program is 177 | void, and will automatically terminate your rights under this License. 178 | However, parties who have received copies, or rights, from you under 179 | this License will not have their licenses terminated so long as such 180 | parties remain in full compliance. 181 | 182 | 5. You are not required to accept this License, since you have not 183 | signed it. However, nothing else grants you permission to modify or 184 | distribute the Program or its derivative works. These actions are 185 | prohibited by law if you do not accept this License. Therefore, by 186 | modifying or distributing the Program (or any work based on the 187 | Program), you indicate your acceptance of this License to do so, and 188 | all its terms and conditions for copying, distributing or modifying 189 | the Program or works based on it. 190 | 191 | 6. Each time you redistribute the Program (or any work based on the 192 | Program), the recipient automatically receives a license from the 193 | original licensor to copy, distribute or modify the Program subject to 194 | these terms and conditions. You may not impose any further 195 | restrictions on the recipients' exercise of the rights granted herein. 196 | You are not responsible for enforcing compliance by third parties to 197 | this License. 198 | 199 | 7. If, as a consequence of a court judgment or allegation of patent 200 | infringement or for any other reason (not limited to patent issues), 201 | conditions are imposed on you (whether by court order, agreement or 202 | otherwise) that contradict the conditions of this License, they do not 203 | excuse you from the conditions of this License. If you cannot 204 | distribute so as to satisfy simultaneously your obligations under this 205 | License and any other pertinent obligations, then as a consequence you 206 | may not distribute the Program at all. For example, if a patent 207 | license would not permit royalty-free redistribution of the Program by 208 | all those who receive copies directly or indirectly through you, then 209 | the only way you could satisfy both it and this License would be to 210 | refrain entirely from distribution of the Program. 211 | 212 | If any portion of this section is held invalid or unenforceable under 213 | any particular circumstance, the balance of the section is intended to 214 | apply and the section as a whole is intended to apply in other 215 | circumstances. 216 | 217 | It is not the purpose of this section to induce you to infringe any 218 | patents or other property right claims or to contest validity of any 219 | such claims; this section has the sole purpose of protecting the 220 | integrity of the free software distribution system, which is 221 | implemented by public license practices. Many people have made 222 | generous contributions to the wide range of software distributed 223 | through that system in reliance on consistent application of that 224 | system; it is up to the author/donor to decide if he or she is willing 225 | to distribute software through any other system and a licensee cannot 226 | impose that choice. 227 | 228 | This section is intended to make thoroughly clear what is believed to 229 | be a consequence of the rest of this License. 230 | 231 | 8. If the distribution and/or use of the Program is restricted in 232 | certain countries either by patents or by copyrighted interfaces, the 233 | original copyright holder who places the Program under this License 234 | may add an explicit geographical distribution limitation excluding 235 | those countries, so that distribution is permitted only in or among 236 | countries not thus excluded. In such case, this License incorporates 237 | the limitation as if written in the body of this License. 238 | 239 | 9. The Free Software Foundation may publish revised and/or new versions 240 | of the General Public License from time to time. Such new versions will 241 | be similar in spirit to the present version, but may differ in detail to 242 | address new problems or concerns. 243 | 244 | Each version is given a distinguishing version number. If the Program 245 | specifies a version number of this License which applies to it and "any 246 | later version", you have the option of following the terms and conditions 247 | either of that version or of any later version published by the Free 248 | Software Foundation. If the Program does not specify a version number of 249 | this License, you may choose any version ever published by the Free Software 250 | Foundation. 251 | 252 | 10. If you wish to incorporate parts of the Program into other free 253 | programs whose distribution conditions are different, write to the author 254 | to ask for permission. For software which is copyrighted by the Free 255 | Software Foundation, write to the Free Software Foundation; we sometimes 256 | make exceptions for this. Our decision will be guided by the two goals 257 | of preserving the free status of all derivatives of our free software and 258 | of promoting the sharing and reuse of software generally. 259 | 260 | NO WARRANTY 261 | 262 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 263 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 264 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 265 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 266 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 267 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 268 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 269 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 270 | REPAIR OR CORRECTION. 271 | 272 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 273 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 274 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 275 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 276 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 277 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 278 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 279 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 280 | POSSIBILITY OF SUCH DAMAGES. 281 | 282 | END OF TERMS AND CONDITIONS 283 | 284 | How to Apply These Terms to Your New Programs 285 | 286 | If you develop a new program, and you want it to be of the greatest 287 | possible use to the public, the best way to achieve this is to make it 288 | free software which everyone can redistribute and change under these terms. 289 | 290 | To do so, attach the following notices to the program. It is safest 291 | to attach them to the start of each source file to most effectively 292 | convey the exclusion of warranty; and each file should have at least 293 | the "copyright" line and a pointer to where the full notice is found. 294 | 295 | 296 | Copyright (C) 297 | 298 | This program is free software; you can redistribute it and/or modify 299 | it under the terms of the GNU General Public License as published by 300 | the Free Software Foundation; either version 2 of the License, or 301 | (at your option) any later version. 302 | 303 | This program is distributed in the hope that it will be useful, 304 | but WITHOUT ANY WARRANTY; without even the implied warranty of 305 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 306 | GNU General Public License for more details. 307 | 308 | You should have received a copy of the GNU General Public License 309 | along with this program; if not, write to the Free Software 310 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 311 | 312 | 313 | Also add information on how to contact you by electronic and paper mail. 314 | 315 | If the program is interactive, make it output a short notice like this 316 | when it starts in an interactive mode: 317 | 318 | Gnomovision version 69, Copyright (C) year name of author 319 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 320 | This is free software, and you are welcome to redistribute it 321 | under certain conditions; type `show c' for details. 322 | 323 | The hypothetical commands `show w' and `show c' should show the appropriate 324 | parts of the General Public License. Of course, the commands you use may 325 | be called something other than `show w' and `show c'; they could even be 326 | mouse-clicks or menu items--whatever suits your program. 327 | 328 | You should also get your employer (if you work as a programmer) or your 329 | school, if any, to sign a "copyright disclaimer" for the program, if 330 | necessary. Here is a sample; alter the names: 331 | 332 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 333 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 334 | 335 | , 1 April 1989 336 | Ty Coon, President of Vice 337 | 338 | This General Public License does not permit incorporating your program into 339 | proprietary programs. If your program is a subroutine library, you may 340 | consider it more useful to permit linking proprietary applications with the 341 | library. If this is what you want to do, use the GNU Library General 342 | Public License instead of this License. 343 | -------------------------------------------------------------------------------- /homeplug_av.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Homeplug AV Ethernet frame definitions 3 | * 4 | * Copyright (C) 2007-2012 Xavier Carcelle 5 | * Florian Fainelli 6 | * Nicolas Thill 7 | * 8 | * The BSD License 9 | * =============== 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in 18 | * the documentation and/or other materials provided with the 19 | * distribution. 20 | * 3. Neither the name of OpenLink Software Inc. nor the names of its 21 | * contributors may be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 38 | /* 39 | * In addition, as a special exception, the copyright holders give 40 | * permission to link the code of portions of this program with the 41 | * OpenSSL library under certain conditions as described in each 42 | * individual source file, and distribute linked combinations 43 | * including the two. 44 | * You must obey the GNU General Public License in all respects 45 | * for all of the code used other than OpenSSL. If you modify 46 | * file(s) with this exception, you may extend this exception to your 47 | * version of the file(s), but you are not obligated to do so. If you 48 | * do not wish to do so, delete this exception statement from your 49 | * version. If you delete this exception statement from all source 50 | * files in the program, then also delete it here. 51 | */ 52 | 53 | #ifndef __HOMEPLUG_AV_H__ 54 | #define __HOMEPLUG_AV_H__ 55 | 56 | #include 57 | #include "faifa_compat.h" 58 | 59 | #define ETHERTYPE_HOMEPLUG_AV 0x88e1 60 | 61 | #define HPAV_VERSION_1_0 0x00 62 | #define HPAV_VERSION_1_1 0x01 63 | 64 | #define HPAV_MM_TYPE_MASK 0x0003 65 | #define HPAV_MM_REQUEST 0x0000 66 | #define HPAV_MM_CONFIRM 0x0001 67 | #define HPAV_MM_INDICATE 0x0002 68 | #define HPAV_MM_RESPONSE 0x0003 69 | 70 | #define HPAV_MM_CATEGORY_MASK 0xE000 71 | #define HPAV_MM_STA_TO_CCO 0x0000 72 | #define HPAV_MM_ANY_TO_PCO 0x2000 73 | #define HPAV_MM_CCO_TO_CCO 0x4000 74 | #define HPAV_MM_STA_TO_STA 0x6000 75 | #define HPAV_MM_MANUF_SPEC 0x8000 76 | #define HPAV_MM_VENDOR_SPEC 0xA000 77 | 78 | #define HPAV_MIN_FRAMSIZ 46 79 | 80 | /*qca specific MMTYPE */ 81 | #define HPAV_MMTYPE_MS_PB_ENC 0x8001 82 | #define HPAV_MMTYPE_MS_ADC_CAP 0x8004 83 | #define HPAV_MMTYPE_MS_DISCOVER 0x8008 84 | 85 | #define HPAV_MMTYPE_CC_DISC_LIST_REQ 0x0014 86 | #define HPAV_MMTYPE_CC_DISC_LIST_CNF 0x0015 87 | #define HPAV_MMTYPE_CM_ENC_PLD_IND 0x6004 88 | #define HPAV_MMTYPE_CM_ENC_PLD_RSP 0x6005 89 | #define HPAV_MMTYPE_CM_SET_KEY_REQ 0x6008 90 | #define HPAV_MMTYPE_CM_SET_KEY_CNF 0x6009 91 | #define HPAV_MMTYPE_CM_GET_KEY_REQ 0x600C 92 | #define HPAV_MMTYPE_CM_GET_KEY_CNF 0x600D 93 | #define HPAV_MMTYPE_CM_BRG_INFO_REQ 0x6020 94 | #define HPAV_MMTYPE_CM_BRG_INFO_CNF 0x6021 95 | #define HPAV_MMTYPE_CM_NW_INFO_REQ 0x6038 96 | #define HPAV_MMTYPE_CM_NW_INFO_CNF 0x6039 97 | #define HPAV_MMTYPE_CM_MME_ERROR_IND 0x6046 98 | #define HPAV_MMTYPE_CM_NW_STATS_REQ 0x6048 99 | #define HPAV_MMTYPE_CM_NW_STATS_CNF 0x6049 100 | #define HPAV_MMTYPE_GET_SW_REQ 0xA000 101 | #define HPAV_MMTYPE_GET_SW_CNF 0xA001 102 | #define HPAV_MMTYPE_WR_MEM_REQ 0xA004 103 | #define HPAV_MMTYPE_WR_MEM_CNF 0xA005 104 | #define HPAV_MMTYPE_RD_MEM_REQ 0xA008 105 | #define HPAV_MMTYPE_RD_MEM_CNF 0xA009 106 | #define HPAV_MMTYPE_ST_MAC_REQ 0xA00C 107 | #define HPAV_MMTYPE_ST_MAC_CNF 0xA00D 108 | #define HPAV_MMTYPE_GET_NVM_REQ 0xA010 109 | #define HPAV_MMTYPE_GET_NVM_CNF 0xA011 110 | #define HPAV_MMTYPE_RS_DEV_REQ 0xA01C 111 | #define HPAV_MMTYPE_RS_DEV_CNF 0xA01D 112 | #define HPAV_MMTYPE_WR_MOD_REQ 0xA020 113 | #define HPAV_MMTYPE_WR_MOD_CNF 0xA021 114 | #define HPAV_MMTYPE_WR_MOD_IND 0xA022 115 | #define HPAV_MMTYPE_RD_MOD_REQ 0xA024 116 | #define HPAV_MMTYPE_RD_MOD_CNF 0xA025 117 | #define HPAV_MMTYPE_NVM_MOD_REQ 0xA028 118 | #define HPAV_MMTYPE_NVM_MOD_CNF 0xA029 119 | #define HPAV_MMTYPE_WD_RPT_REQ 0xA02C 120 | #define HPAV_MMTYPE_WD_RPT_IND 0xA02E 121 | #define HPAV_MMTYPE_LNK_STATS_REQ 0xA030 122 | #define HPAV_MMTYPE_LNK_STATS_CNF 0xA031 123 | #define HPAV_MMTYPE_SNIFFER_REQ 0xA034 124 | #define HPAV_MMTYPE_SNIFFER_CNF 0xA035 125 | #define HPAV_MMTYPE_SNIFFER_IND 0xA036 126 | #define HPAV_MMTYPE_NW_INFO_REQ 0xA038 127 | #define HPAV_MMTYPE_NW_INFO_CNF 0xA039 128 | #define HPAV_MMTYPE_CP_RPT_REQ 0xA040 129 | #define HPAV_MMTYPE_CP_RPT_IND 0xA042 130 | #define HPAV_MMTYPE_FR_LBK_REQ 0xA048 131 | #define HPAV_MMTYPE_FR_LBK_CNF 0xA049 132 | #define HPAV_MMTYPE_LBK_STAT_REQ 0xA04C 133 | #define HPAV_MMTYPE_LBK_STAT_CNF 0xA04D 134 | #define HPAV_MMTYPE_SET_KEY_REQ 0xA050 135 | #define HPAV_MMTYPE_SET_KEY_CNF 0xA051 136 | #define HPAV_MMTYPE_MFG_STRING_REQ 0xA054 137 | #define HPAV_MMTYPE_MFG_STRING_CNF 0xA055 138 | #define HPAV_MMTYPE_RD_CBLOCK_REQ 0xA058 139 | #define HPAV_MMTYPE_RD_CBLOCK_CNF 0xA059 140 | #define HPAV_MMTYPE_SET_SDRAM_REQ 0xA05C 141 | #define HPAV_MMTYPE_SET_SDRAM_CNF 0xA05D 142 | #define HPAV_MMTYPE_HOST_ACTION_IND 0xA062 143 | #define HPAV_MMTYPE_HOST_ACTION_RSP 0xA063 144 | #define HPAV_MMTYPE_OP_ATTR_REQ 0xA068 145 | #define HPAV_MMTYPE_OP_ATTR_CNF 0xA069 146 | #define HPAV_MMTYPE_GET_ENET_PHY_REQ 0xA06C 147 | #define HPAV_MMTYPE_GET_ENET_PHY_CNF 0xA06D 148 | #define HPAV_MMTYPE_TONE_MAP_REQ 0xA070 149 | #define HPAV_MMTYPE_TONE_MAP_CNF 0xA071 150 | 151 | /** 152 | * hpav_frame_header - HomePlug AV frame header 153 | * @mmver: MM version of the frame 154 | * @mmtype: MM type for this frame 155 | */ 156 | struct hpav_frame_header { 157 | u_int8_t mmver; 158 | u_int16_t mmtype; 159 | } __attribute__((__packed__)); 160 | 161 | /** 162 | * hpav_frame_public_payload - HomePlug AV Public MMEs payload 163 | * @data: Frame-Specific data 164 | */ 165 | struct hpav_frame_public_payload { 166 | u_int8_t frag_count:4; 167 | u_int8_t frag_index:4; 168 | u_int8_t frag_seqnum; 169 | u_int8_t data[0]; 170 | } __attribute__((__packed__)); 171 | 172 | /** 173 | * hpav_frame_vendor_payload - HomePlug AV Vendor-Specific MMEs payload 174 | * @oui: Vendor OUI (Intellon OUI : 0x00, 0xb0, 0x52) 175 | * @data: Frame-Specific data 176 | */ 177 | struct hpav_frame_vendor_payload { 178 | u_int8_t oui[3]; 179 | u_int8_t data[0]; 180 | } __attribute__((__packed__)); 181 | 182 | /** 183 | * hpav_frame - HomePlug AV frame 184 | * @header: hpav_frame_header 185 | * @public Public variant part 186 | * @vendor Vendor-Specific variant part 187 | */ 188 | struct hpav_frame { 189 | struct hpav_frame_header header; 190 | union { 191 | struct hpav_frame_public_payload pub; 192 | struct hpav_frame_vendor_payload vendor; 193 | } __attribute__((__packed__)) payload; 194 | } __attribute__((__packed__)); 195 | 196 | /** 197 | * hpav_frame_ops - Homeplug AV ethernet frames operations 198 | * @mmtype: frame specific MM type 199 | * @desc: frame description 200 | * @init_frame: frame specific initialisation callback 201 | * @dump_frame: frame specific dump callback 202 | */ 203 | struct hpav_frame_ops { 204 | u_int16_t mmtype; 205 | char *desc; 206 | int (*init_frame)(void *buf, int len, void *user); 207 | int (*dump_frame)(void *buf, int len, struct ether_header *hdr); 208 | }; 209 | 210 | /* Central Coordination Discover List MME */ 211 | 212 | struct cc_sta_info { 213 | u_int8_t macaddr[6]; 214 | u_int8_t tei; 215 | u_int8_t same_network; 216 | u_int8_t snid; 217 | u_int8_t rsvd; 218 | u_int8_t cco_cap; 219 | u_int8_t sig_level; 220 | } __attribute__((__packed__)); 221 | 222 | struct cc_sta_infos { 223 | u_int8_t count; 224 | struct cc_sta_info infos[0]; 225 | } __attribute__((__packed__)); 226 | 227 | struct cc_net_info { 228 | u_int8_t nid[7]; 229 | u_int8_t snid; 230 | u_int8_t hybrid_mode; 231 | u_int8_t num_bcn_slots; 232 | u_int8_t cco_status; 233 | u_int16_t bcn_offset; 234 | } __attribute__((__packed__)); 235 | 236 | struct cc_net_infos { 237 | u_int8_t count; 238 | struct cc_net_info infos[0]; 239 | } __attribute__((__packed__)); 240 | 241 | /* 0014 - CC Discover List Request */ 242 | 243 | /* 0015 - CC Discover List Confirm */ 244 | struct cc_discover_list_confirm { 245 | struct cc_sta_infos sta[0]; 246 | struct cc_net_infos net[0]; 247 | } __attribute__((__packed__)); 248 | 249 | /* Get Device/SW Version MME */ 250 | 251 | /* 0xA000 - Get Device/SW Version Request */ 252 | 253 | /* 0xA001 - Get Device/SW Version Confirm */ 254 | struct get_device_sw_version_confirm { 255 | u_int8_t mstatus; 256 | u_int8_t device_id; 257 | u_int8_t version_length; 258 | u_int8_t version[64]; 259 | u_int8_t upgradeable; 260 | } __attribute__((__packed__)); 261 | 262 | #define INT6000_DEVICE_ID 0x1 263 | #define INT6300_DEVICE_ID 0x2 264 | #define INT6400_DEVICE_ID 0x3 265 | 266 | /* Write MAC Memory MME */ 267 | 268 | /* A004 - Write MAC Memory Request */ 269 | struct write_mac_memory_request { 270 | u_int32_t address; 271 | u_int32_t length; 272 | u_int8_t data[0]; 273 | } __attribute__((__packed__)); 274 | 275 | /* A005 - Write MAC Memory Confirm */ 276 | struct write_mac_memory_confirm { 277 | u_int8_t mstatus; 278 | u_int32_t address; 279 | u_int32_t length; 280 | } __attribute__((__packed__)); 281 | 282 | 283 | /* Read MAC Memory MME */ 284 | 285 | /* A008 - Read MAC Memory Request */ 286 | struct read_mac_memory_request { 287 | u_int32_t address; 288 | u_int32_t length; 289 | } __attribute__((__packed__)); 290 | 291 | /* A009 - Read MAC Memory Confirm */ 292 | struct read_mac_memory_confirm { 293 | u_int8_t mstatus; 294 | u_int32_t address; 295 | u_int32_t length; 296 | u_int8_t data[0]; 297 | } __attribute__((__packed__)); 298 | 299 | 300 | /* Start MAC MME */ 301 | 302 | /* Module ID */ 303 | enum module_id { 304 | MAC_SL_IMG = 0x00, 305 | MAC_SW_IMG = 0x01, 306 | PIB = 0x02, 307 | WR_ALT_FLSH = 0x10, 308 | } __attribute__((__packed__)); 309 | 310 | /* A00C - Start MAC Request */ 311 | struct start_mac_request { 312 | u_int8_t module_id; 313 | u_int8_t reserved1[3]; 314 | u_int32_t image_load; 315 | u_int32_t image_length; 316 | u_int32_t image_chksum; 317 | u_int32_t image_saddr; 318 | } __attribute__((__packed__)); 319 | 320 | /* A00D - Start MAC Confirm */ 321 | struct start_mac_confirm { 322 | u_int8_t mstatus; 323 | u_int8_t module_id; 324 | } __attribute__((__packed__)); 325 | 326 | 327 | /* Get NVM Parameters MME */ 328 | 329 | /* A010 - Get NVM Parameters Request */ 330 | 331 | /* A011 - Get NVM Parameters Confirm */ 332 | struct get_nvm_parameters_confirm { 333 | u_int8_t mstatus; 334 | u_int32_t manuf_code; 335 | u_int32_t page_size; 336 | u_int32_t block_size; 337 | u_int32_t mem_size; 338 | } __attribute__((__packed__)); 339 | 340 | 341 | /* Reset Device MME */ 342 | 343 | /* A01C - Reset Device Request */ 344 | 345 | /* A01D - Reset Device Confirm */ 346 | struct reset_device_confirm { 347 | u_int8_t mstatus; 348 | } __attribute__((__packed__)); 349 | 350 | 351 | /* Write Module Data MME */ 352 | 353 | enum write_module_id { 354 | SUCCESS = 0x00, 355 | INV_MOD_ID = 0x10, 356 | BAD_HDR_CHKSUM = 0x18, 357 | INV_LEN = 0x1C, 358 | UNEX_OFF = 0x20, 359 | INV_CHKSUM = 0x14, 360 | } __attribute__((__packed__)); 361 | 362 | /* A020 - Write Module Data Request */ 363 | struct write_mod_data_request { 364 | u_int8_t module_id; 365 | u_int8_t reserved1[1]; 366 | u_int16_t length; 367 | u_int32_t offset; 368 | u_int32_t checksum; 369 | u_int8_t data[0]; 370 | } __attribute__((__packed__)); 371 | 372 | /* A021 - Write Module Data Confirm */ 373 | struct write_mod_data_confirm { 374 | u_int8_t mstatus; 375 | u_int8_t module_id; 376 | u_int8_t reserved1[1]; 377 | u_int16_t length; 378 | u_int32_t offset; 379 | } __attribute__((__packed__)); 380 | 381 | /* A022 - Write Module Data Indicate */ 382 | struct write_mod_data_indicate { 383 | u_int8_t mstatus; 384 | u_int8_t module_id; 385 | } __attribute__((__packed__)); 386 | 387 | 388 | /* Read Module Data MME */ 389 | 390 | /* A024 - Read Module Data Request */ 391 | struct read_mod_data_request { 392 | u_int8_t module_id; 393 | u_int8_t reserved1[1]; 394 | u_int16_t length; 395 | u_int32_t offset; 396 | } __attribute__((__packed__)); 397 | 398 | /* A025 - Read Module Data Confirm */ 399 | struct read_mod_data_confirm { 400 | u_int8_t mstatus; 401 | u_int8_t reserved1[3]; 402 | u_int8_t module_id; 403 | u_int8_t reserved2[1]; 404 | u_int16_t length; 405 | u_int32_t offset; 406 | u_int32_t checksum; 407 | u_int8_t data[0]; 408 | } __attribute__((__packed__)); 409 | 410 | 411 | /* Write Module Data to NVM MME */ 412 | 413 | /* A028 - Write Module Data to NVM Request */ 414 | struct write_module_data_to_nvm_request { 415 | u_int8_t module_id; 416 | } __attribute__((__packed__)); 417 | 418 | /* A029 - Write Module Data to NVM Confirm */ 419 | struct write_module_data_to_nvm_confirm { 420 | u_int8_t mstatus; 421 | u_int8_t module_id; 422 | } __attribute__((__packed__)); 423 | 424 | 425 | /* Get Watchdog Report MME */ 426 | 427 | /* A02C - Get Watchdog Report Request */ 428 | struct get_watchdog_report_request { 429 | u_int16_t session_id; 430 | u_int8_t clr_flag; 431 | } __attribute__((__packed__)); 432 | 433 | /* A02E - Get Watchdog Report Indicate */ 434 | struct get_watchdog_report_indicate { 435 | u_int8_t mstatus; 436 | u_int16_t session_id; 437 | u_int8_t num_parts; 438 | u_int8_t cur_part; 439 | u_int16_t data_length; 440 | u_int8_t data_offset; 441 | u_int8_t data[0]; 442 | } __attribute__((__packed__)); 443 | 444 | 445 | /* Link Statistics MME */ 446 | 447 | /* Status types */ 448 | enum statistics_status { 449 | HPAV_SUC = 0x00, 450 | HPAV_INV_CTL = 0x01, 451 | HPAV_INV_DIR = 0x02, 452 | HPAV_INV_LID = 0x10, 453 | HPAV_INV_MAC = 0x20, 454 | }; 455 | 456 | /* Direction types */ 457 | enum statistics_direction { 458 | HPAV_SD_TX = 0x00, 459 | HPAV_SD_RX = 0x01, 460 | HPAV_SD_BOTH = 0x02, 461 | }; 462 | 463 | enum link_id { 464 | HPAV_LID_CSMA_CAP_0 = 0x00, 465 | HPAV_LID_CSMA_CAP_1 = 0x01, 466 | HPAV_LID_CSMA_CAP_2 = 0x02, 467 | HPAV_LID_CSMA_CAP_3 = 0x03, 468 | HPAV_LID_CSMA_SUM = 0xF8, 469 | HPAV_LID_CSMA_SUM_ANY = 0xFC, 470 | }; 471 | 472 | struct rx_interval_stats { 473 | u_int8_t phyrate; 474 | u_int64_t pb_passed; 475 | u_int64_t pb_failed; 476 | u_int64_t tbe_passed; 477 | u_int64_t tbe_failed; 478 | } __attribute__((__packed__)); 479 | 480 | struct tx_link_stats { 481 | u_int64_t mpdu_ack; 482 | u_int64_t mpdu_coll; 483 | u_int64_t mpdu_fail; 484 | u_int64_t pb_passed; 485 | u_int64_t pb_failed; 486 | } __attribute__((__packed__)); 487 | 488 | struct rx_link_stats { 489 | u_int64_t mpdu_ack; 490 | u_int64_t mpdu_fail; 491 | u_int64_t pb_passed; 492 | u_int64_t pb_failed; 493 | u_int64_t tbe_passed; 494 | u_int64_t tbe_failed; 495 | u_int8_t num_rx_intervals; 496 | struct rx_interval_stats rx_interval_stats[0]; 497 | } __attribute__((__packed__)); 498 | 499 | /* A030 - Link Statistics Request */ 500 | struct link_statistics_request { 501 | u_int8_t control; 502 | u_int8_t direction; 503 | u_int8_t link_id; 504 | u_int8_t macaddr[6]; 505 | } __attribute__((__packed__)); 506 | 507 | /* A031 - Link Statistics Confirm */ 508 | struct link_statistics_confirm { 509 | u_int8_t mstatus; 510 | u_int8_t direction; 511 | u_int8_t link_id; 512 | u_int8_t tei; 513 | union { 514 | struct tx_link_stats tx; 515 | struct rx_link_stats rx; 516 | struct { 517 | struct tx_link_stats tx; 518 | struct rx_link_stats rx; 519 | } __attribute__((__packed__)) both; 520 | } __attribute__((__packed__)); 521 | } __attribute__((__packed__)); 522 | 523 | 524 | /* Sniffer MME */ 525 | 526 | /* Sniffer Control */ 527 | enum sniffer_control { 528 | HPAV_SC_DISABLE = 0x00, 529 | HPAV_SC_ENABLE = 0x01, 530 | HPAV_SC_NO_CHANGE = 0x02, 531 | }; 532 | 533 | enum sniffer_state { 534 | HPAV_ST_DISABLED = 0x00, 535 | HPAV_ST_ENABLED = 0x01, 536 | }; 537 | 538 | struct hpav_fc { 539 | u_int8_t del_type:3; 540 | u_int8_t access:1; 541 | u_int8_t snid:4; 542 | u_int8_t stei; 543 | u_int8_t dtei; 544 | u_int8_t lid; 545 | u_int8_t cfs:1; 546 | u_int8_t bdf:1; 547 | u_int8_t hp10df:1; 548 | u_int8_t hp11df:1; 549 | u_int8_t eks:4; 550 | u_int8_t ppb; 551 | u_int8_t ble; 552 | u_int8_t pbsz:1; 553 | u_int8_t num_sym:2; 554 | u_int8_t tmi_av:5; 555 | u_int16_t fl_av:12; 556 | u_int8_t mpdu_cnt:2; 557 | u_int8_t burst_cnt:2; 558 | u_int8_t clst:3; 559 | u_int8_t rg_len_lo:5; 560 | u_int8_t rg_len_hi:1; 561 | u_int8_t mfs_cmd_mgmt:3; 562 | u_int8_t mfs_cmd_data:3; 563 | u_int8_t rsr:1; 564 | u_int8_t mcf:1; 565 | u_int8_t dccpcf:1; 566 | u_int8_t mnbf:1; 567 | u_int8_t rsvd:5; 568 | u_int8_t fccs_av[3]; 569 | } __attribute__((__packed__)); 570 | 571 | struct hpav_bcn { 572 | u_int8_t del_type:3; 573 | u_int8_t access:1; 574 | u_int8_t snid:4; 575 | u_int32_t bts; 576 | u_int16_t bto_0; 577 | u_int16_t bto_1; 578 | u_int16_t bto_2; 579 | u_int16_t bto_3; 580 | u_int8_t fccs_av[3]; 581 | } __attribute__((__packed__)); 582 | 583 | /* 0xA034 - Sniffer Request */ 584 | struct sniffer_request { 585 | u_int8_t control; 586 | u_int8_t reserved1[4]; 587 | } __attribute__((__packed__)); 588 | 589 | /* 0xA035 - Sniffer Confirm */ 590 | struct sniffer_confirm { 591 | u_int8_t mstatus; 592 | u_int8_t state; 593 | u_int8_t da[6]; 594 | } __attribute__((__packed__)); 595 | 596 | /* 0xA036 - Sniffer Indicate */ 597 | struct sniffer_indicate { 598 | u_int8_t type; 599 | u_int8_t direction; 600 | u_int64_t systime; 601 | u_int32_t beacontime; 602 | struct hpav_fc fc; 603 | struct hpav_bcn bcn; 604 | } __attribute__((__packed__)); 605 | 606 | 607 | /* Network Info MME */ 608 | 609 | enum sta_role { 610 | HPAV_SR_STA = 0x00, 611 | HPAV_SR_PROXY = 0x01, 612 | HPAV_SR_CCO = 0x02, 613 | }; 614 | 615 | struct sta_info { 616 | u_int8_t sta_macaddr[6]; 617 | u_int8_t sta_tei; 618 | u_int8_t bridge_macaddr[6]; 619 | u_int8_t avg_phy_tx_rate; 620 | u_int8_t avg_phy_rx_rate; 621 | } __attribute__((__packed__)); 622 | 623 | /* 0xA038 - Network Info Request */ 624 | 625 | /* 0xA039 - Network Info Confirm */ 626 | struct network_info_confirm { 627 | u_int8_t num_avlns; 628 | u_int8_t nid[7]; 629 | u_int8_t snid; 630 | u_int8_t tei; 631 | u_int8_t sta_role; 632 | u_int8_t cco_macaddr[6]; 633 | u_int8_t cco_tei; 634 | u_int8_t num_stas; 635 | struct sta_info stas[0]; 636 | } __attribute__((__packed__)); 637 | 638 | 639 | /* Check Points MME */ 640 | 641 | /* A040 - Check Points Request */ 642 | struct check_points_request { 643 | u_int16_t session_id; 644 | u_int8_t clr_flag; 645 | } __attribute__((__packed__)); 646 | 647 | /* A042 - Check Points Indicate */ 648 | struct check_points_indicate { 649 | u_int8_t mstatus:3; 650 | u_int8_t major:1; 651 | u_int8_t buf_locked:1; 652 | u_int8_t auto_lock:1; 653 | u_int8_t unsoc_upd:1; 654 | u_int8_t unsoc:1; 655 | u_int8_t reserved1[14]; 656 | u_int16_t session_id; 657 | u_int32_t length; 658 | u_int32_t offset; 659 | u_int32_t index; 660 | u_int8_t num_parts; 661 | u_int8_t cur_part; 662 | u_int16_t data_length; 663 | u_int16_t data_offset; 664 | u_int8_t data[0]; 665 | } __attribute__((__packed__)); 666 | 667 | 668 | /* Loopback MME */ 669 | 670 | /* A048 - Loopback Request */ 671 | struct loopback_request { 672 | u_int8_t duration; 673 | u_int8_t reserved1[0]; 674 | u_int16_t length; 675 | u_int8_t data[0]; 676 | } __attribute__((__packed__)); 677 | 678 | /* A049 - Loopback Confirm */ 679 | struct loopback_confirm { 680 | u_int8_t mstatus; 681 | u_int8_t duration; 682 | u_int16_t length; 683 | } __attribute__((__packed__)); 684 | 685 | 686 | /* Loopback Status MME */ 687 | 688 | /* A04C - Loopback Status Request */ 689 | 690 | /* A04D - Loopback Status Confirm */ 691 | struct loopback_status_confirm { 692 | u_int8_t mstatus; 693 | u_int8_t state; 694 | } __attribute__((__packed__)); 695 | 696 | 697 | /* Set Encryption Key MME */ 698 | 699 | enum set_enc_key_status { 700 | KEY_SUCCESS = 0x00, 701 | KEY_INV_EKS = 0x10, 702 | KEY_INV_PKS = 0x11, 703 | KEY_UKN = 0x12, 704 | }; 705 | 706 | #define AES_KEY_SIZE 16 707 | 708 | /* A050 - Set Encryption Key Request */ 709 | struct set_encryption_key_request { 710 | u_int8_t peks; 711 | u_int8_t nmk[AES_KEY_SIZE]; 712 | u_int8_t peks_payload; 713 | u_int8_t rdra[6]; 714 | u_int8_t dak[AES_KEY_SIZE]; 715 | } __attribute__((__packed__)); 716 | 717 | /* A051 - Set Encryption Key Confirm */ 718 | struct set_encryption_key_confirm { 719 | u_int8_t mstatus; 720 | }; 721 | 722 | 723 | /* Get Manufacturing String MME */ 724 | 725 | /* A054 - Get Manufacturing String Request */ 726 | 727 | /* A055 - Get Manufacturing String Confirm */ 728 | struct get_manuf_string_confirm { 729 | u_int8_t status; 730 | u_int8_t length; 731 | u_int8_t data[64]; 732 | } __attribute__((__packed__)); 733 | 734 | 735 | /* Read Configuration Block & SDRAM Configuration MME */ 736 | 737 | enum sdram_status { 738 | SDR_INV_CHKSUM = 0x30, 739 | SDR_BIST_FAILED = 0x34, 740 | }; 741 | 742 | struct sdram_config { 743 | u_int32_t size; 744 | u_int32_t conf_reg; 745 | u_int32_t timing0; 746 | u_int32_t timing1; 747 | u_int32_t ctl_reg; 748 | u_int32_t ref_reg; 749 | u_int32_t clk_reg_val; 750 | u_int32_t reserved; 751 | } __attribute__ ((__packed__)); 752 | 753 | struct block_header { 754 | u_int32_t version; 755 | u_int32_t img_rom_addr; 756 | u_int32_t img_sdram_addr; 757 | u_int32_t img_length; 758 | u_int32_t img_checksum; 759 | u_int32_t entry_point; 760 | u_int8_t reserved[12]; 761 | u_int32_t next_header; 762 | u_int32_t hdr_checksum; 763 | } __attribute__((__packed__)); 764 | 765 | /* A058 - Read Configuration Block Request */ 766 | 767 | /* A059 - Read Configuration Block Confirm */ 768 | struct read_config_block_confirm { 769 | u_int8_t mstatus; 770 | u_int8_t config_length; 771 | struct block_header hdr; 772 | struct sdram_config config; 773 | } __attribute__((__packed__)); 774 | 775 | /* A05C - Set SDRAM Configuration Request */ 776 | struct set_sdram_config_request { 777 | struct sdram_config config; 778 | u_int32_t checksum; 779 | } __attribute__((__packed__)); 780 | 781 | /* A05D - Set SDRAM Configuration Confirm */ 782 | struct set_sdram_config_confirm { 783 | u_int8_t mstatus; 784 | } __attribute__((__packed__)); 785 | 786 | 787 | /* Embedded Host Action Required MME */ 788 | 789 | enum host_actions { 790 | LOADER = 0x00, 791 | FIRM_UP_RDY = 0x01, 792 | PIB_UP_RDY = 0x02, 793 | FIRM_UP_PIB_RDY = 0x03, 794 | LOADER_SDR_RDY = 0x04, 795 | }; 796 | 797 | /* A062 - Embedded Host Action Required Indicate */ 798 | struct embedded_host_action_indicate { 799 | u_int8_t action; 800 | } __attribute__((__packed__)); 801 | 802 | /* A063 - Embedded Host Action Required Response */ 803 | struct embedded_host_action_response { 804 | u_int8_t mstatus; 805 | } __attribute__((__packed__)); 806 | 807 | 808 | /* Get Devices Attributes MME */ 809 | 810 | struct get_devices_attrs_fmt { 811 | u_int8_t hardware[16]; 812 | u_int8_t software[16]; 813 | u_int32_t major; 814 | u_int32_t minor; 815 | u_int32_t subversion; 816 | u_int32_t build_number; 817 | u_int8_t rsvd[8]; 818 | u_int8_t build_date[8]; 819 | u_int8_t release_type[12]; 820 | } __attribute__((__packed__)); 821 | 822 | /* A068 - Get Devices Attributes Request */ 823 | struct get_devices_attrs_request { 824 | u_int32_t cookie; 825 | u_int8_t rtype; 826 | } __attribute__((__packed__)); 827 | 828 | /* A069 - Get Devices Attributes Confirm */ 829 | struct get_devices_attrs_confirm { 830 | u_int16_t status; 831 | u_int32_t cookie; 832 | u_int8_t rtype; 833 | u_int16_t size; 834 | struct get_devices_attrs_fmt fmt; 835 | } __attribute__((__packed__)); 836 | 837 | 838 | /* Ethernet PHY Settings MME */ 839 | 840 | enum enet_speed { 841 | ENET = 0x00, 842 | FA_ENET = 0x01, 843 | GIG_ENET = 0x02, 844 | }; 845 | 846 | /* AO6C - Get Ethernet PHY Settings Request */ 847 | struct get_enet_phy_settings_request { 848 | u_int8_t mcontrol; 849 | u_int8_t addcaps; 850 | u_int8_t reserved[3]; 851 | } __attribute__((__packed__)); 852 | 853 | /* AO6D - Get Ethernet PHY Settings Confirm */ 854 | struct get_enet_phy_settings_confirm { 855 | u_int8_t status; 856 | u_int8_t speed; 857 | u_int8_t duplex; 858 | } __attribute__((__packed__)); 859 | 860 | 861 | /* Tone Map Characteristics MME */ 862 | 863 | /* Various carrier modulations */ 864 | enum mod_carrier { 865 | NO = 0x0, 866 | BPSK = 0x1, 867 | QPSK = 0x2, 868 | QAM_8 = 0x3, 869 | QAM_16 = 0x4, 870 | QAM_64 = 0x5, 871 | QAM_256 = 0x6, 872 | QAM_1024 = 0x7, 873 | }; 874 | 875 | struct modulation_stats { 876 | unsigned no; 877 | unsigned bpsk; 878 | unsigned qpsk; 879 | unsigned qam8; 880 | unsigned qam16; 881 | unsigned qam64; 882 | unsigned qam256; 883 | unsigned qam1024; 884 | unsigned unknown; 885 | }; 886 | 887 | /* Statistics group two carrier on 4 bits */ 888 | struct carrier { 889 | u_int8_t mod_carrier_lo:4; 890 | u_int8_t mod_carrier_hi:4; 891 | } __attribute__((__packed__)); 892 | 893 | /* A070 - Tone Map Characteristics Request */ 894 | struct get_tone_map_charac_request { 895 | u_int8_t macaddr[6]; 896 | u_int8_t tmslot; 897 | } __attribute__((__packed__)); 898 | 899 | /* A071 - Tone Map Characteristics Confirm */ 900 | struct get_tone_map_charac_confirm { 901 | u_int8_t mstatus; 902 | u_int8_t tmslot; 903 | u_int8_t num_tms; 904 | u_int16_t tm_num_act_carrier; 905 | struct carrier carriers[0]; 906 | } __attribute__((__packed__)); 907 | 908 | 909 | /* Encrypted Payload MME */ 910 | 911 | enum peks_val { 912 | DST_STA_DAK = 0x00, 913 | NMK_KNOWN_STA = 0x01, 914 | ID_TEKS = 0x02, /* to OxE */ 915 | NO_KEY = 0x0F, 916 | }; 917 | 918 | enum avln_status { 919 | UN_ASSOC_LVL_0 = 0x00, 920 | UN_ASSOC_LVL_1 = 0x01, 921 | UN_ASSOC_LVL_2 = 0x02, 922 | UN_ASSOC_LVL_3 = 0x03, 923 | UN_ASSOC_NPCO = 0x04, 924 | UN_ASSOC_PCO = 0x05, 925 | CCO_AVLN = 0x08, 926 | }; 927 | 928 | enum pid { 929 | AUTH_REQ_NEW = 0x00, 930 | PROV_STA_NEW = 0x01, 931 | PROV_STA_DAK = 0x02, 932 | PROV_STA_UKE = 0x03, 933 | HLE_PROTO = 0x04, 934 | }; 935 | 936 | struct cm_enc_payload_mm { 937 | u_int16_t len; 938 | u_int8_t mme[0]; 939 | } __attribute__((__packed__)); 940 | 941 | struct cm_enc_payload_hle_payload { 942 | u_int16_t len; 943 | u_int8_t random_filler[0]; 944 | u_int8_t payload; 945 | u_int32_t crc; 946 | u_int8_t pid; 947 | u_int8_t prn; 948 | u_int8_t pmn; 949 | u_int8_t padding[0]; 950 | u_int8_t rf_len[0]; 951 | } __attribute__((__packed__)); 952 | 953 | /* 6004 - Encrypted Payload Indicate */ 954 | struct cm_enc_payload_indicate { 955 | u_int8_t peks; 956 | u_int8_t avln_status; 957 | u_int8_t pid; 958 | u_int8_t prn; 959 | u_int8_t pmn; 960 | u_int8_t aes_iv_uuid[AES_KEY_SIZE]; 961 | union { 962 | struct cm_enc_payload_mm mm; 963 | struct cm_enc_payload_hle_payload payload; 964 | } __attribute__((__packed__)); 965 | } __attribute__((__packed__)); 966 | 967 | /* 6005 - Encrypted Payload Response */ 968 | struct cm_enc_payload_response { 969 | u_int8_t result; 970 | u_int8_t pid; 971 | u_int16_t prn; 972 | } __attribute__((__packed__)); 973 | 974 | 975 | /* Set Key MME */ 976 | 977 | enum key_type { 978 | DAK_AES_128 = 0x00, 979 | NMK_AES_128 = 0x01, 980 | NEK_AES_128 = 0x02, 981 | TEK_AES_128 = 0x03, 982 | HASH_KEY = 0x04, 983 | NONCE_ONLY = 0x05, 984 | }; 985 | 986 | /* 6008 - Set Key Request */ 987 | struct cm_set_key_request { 988 | u_int8_t key_type; 989 | u_int32_t my_nonce; 990 | u_int32_t your_nonce; 991 | u_int8_t pid; 992 | u_int16_t prn; 993 | u_int8_t pmn; 994 | u_int8_t cco_cap; 995 | u_int8_t nid[7]; 996 | u_int8_t new_eks; 997 | u_int8_t new_key[0]; /* or AES_KEY_SIZE */ 998 | } __attribute__((__packed__)); 999 | 1000 | /* 6009 - Set Key Confirm */ 1001 | struct cm_set_key_confirm { 1002 | u_int8_t result; 1003 | u_int32_t my_nonce; 1004 | u_int32_t your_nonce; 1005 | u_int8_t pid; 1006 | u_int16_t prn; 1007 | u_int8_t pmn; 1008 | u_int8_t cco_cap; 1009 | } __attribute__((__packed__)); 1010 | 1011 | 1012 | /* Get Key MME */ 1013 | 1014 | /* 600C - Get Key Request */ 1015 | struct cm_get_key_request { 1016 | u_int8_t req_type; 1017 | u_int8_t req_key_type; 1018 | u_int8_t nid[7]; 1019 | u_int32_t my_nonce; 1020 | u_int8_t pid; 1021 | u_int16_t prn; 1022 | u_int8_t pmn; 1023 | u_int8_t hash_key[0]; 1024 | } __attribute__((__packed__)); 1025 | 1026 | /* 600D - Get Key Confirm */ 1027 | struct cm_get_key_confirm { 1028 | u_int8_t result; 1029 | u_int8_t req_key_type; 1030 | u_int32_t my_nonce; 1031 | u_int32_t your_nonce; 1032 | u_int8_t nid[7]; 1033 | u_int8_t eks; 1034 | u_int8_t pid; 1035 | u_int16_t prn; 1036 | u_int8_t pmn; 1037 | u_int8_t key[0]; 1038 | } __attribute__((__packed__)); 1039 | 1040 | 1041 | /* Get Bridge Infos MME */ 1042 | 1043 | struct bridge_infos { 1044 | u_int8_t btei; 1045 | u_int8_t nbda; 1046 | u_int8_t bri_addr[0][6]; 1047 | }; 1048 | 1049 | /* 6020 - Get Bridge Infos Request */ 1050 | 1051 | /* 6021 - Get Bridge Infos Confirm */ 1052 | struct cm_brigde_infos_confirm { 1053 | u_int8_t bsf; 1054 | union { 1055 | struct bridge_infos bridge_infos; 1056 | } __attribute__((__packed__)); 1057 | } __attribute__((__packed__)); 1058 | 1059 | 1060 | /* Get Network Infos MME */ 1061 | 1062 | struct cm_net_info { 1063 | u_int8_t nid[7]; 1064 | u_int8_t snid; 1065 | u_int8_t tei; 1066 | u_int8_t sta_role; 1067 | u_int8_t macaddr[6]; 1068 | u_int8_t access; 1069 | u_int8_t num_cord; 1070 | } __attribute__((__packed__)); 1071 | 1072 | struct cm_net_infos { 1073 | u_int8_t count; 1074 | struct cm_net_info infos[0]; 1075 | } __attribute__((__packed__)); 1076 | 1077 | /* 6038 - Get Network Infos Request */ 1078 | 1079 | /* 6039 - Get Network Infos Confirm */ 1080 | struct cm_get_network_infos_confirm { 1081 | struct cm_net_infos net; 1082 | } __attribute__((__packed__)); 1083 | 1084 | enum err_reason_code { 1085 | MME_NOT_SUP = 0, 1086 | INVALID_MME_FIELDS = 1, 1087 | UNSUPPORTED_FEATURE = 2, 1088 | }; 1089 | 1090 | /* 6046 - MME Error Indication */ 1091 | struct cm_mme_error_ind { 1092 | u_int8_t err_reason_code; 1093 | u_int8_t rx_version; 1094 | u_int16_t rx_mmtype; 1095 | u_int16_t invalid_offset; 1096 | } __attribute__((__packed__)); 1097 | 1098 | /* Get Network Stats MME */ 1099 | 1100 | struct cm_sta_info { 1101 | u_int8_t macaddr[6]; 1102 | u_int8_t avg_phy_dr_tx; 1103 | u_int8_t avg_phy_dr_rx; 1104 | } __attribute__((__packed__)); 1105 | 1106 | struct cm_sta_infos { 1107 | u_int8_t count; 1108 | struct cm_sta_info infos[0]; 1109 | } __attribute__((__packed__)); 1110 | 1111 | /* 6048 - Get Network Stats Request */ 1112 | 1113 | /* 6049 - Get Network Stats Confirm */ 1114 | struct cm_get_network_stats_confirm { 1115 | struct cm_sta_infos sta; 1116 | } __attribute__((__packed__)); 1117 | 1118 | #endif /* __HOMEPLUG_AV_H__ */ 1119 | --------------------------------------------------------------------------------