faifa-0.2~svn82.orig/0000755000175000017500000000000011562301765014361 5ustar drazzibdrazzibfaifa-0.2~svn82.orig/LICENCE.OpenSSL0000644000175000017500000001417511251226102016622 0ustar drazzibdrazzibLICENSE ISSUES ============== The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL please contact openssl-core@openssl.org. OpenSSL License --------------- /* ==================================================================== * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ Original SSLeay License ----------------------- /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ faifa-0.2~svn82.orig/faifa.c0000644000175000017500000001763311546610111015573 0ustar drazzibdrazzib/* * Core library functions * * Copyright (C) 2007-2009 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #ifndef __CYGWIN__ #include #endif #include #include #include #include #include #include #include "faifa.h" #include "faifa_compat.h" #include "faifa_priv.h" #include "homeplug_av.h" void faifa_set_error(faifa_t *faifa, char *format, ...) { va_list ap; if (!faifa) return; va_start(ap, format); vsnprintf(faifa->error, sizeof(faifa->error), format, ap); va_end(ap); } faifa_t *faifa_init(void) { faifa_t *faifa; faifa = calloc(1, sizeof(faifa_t)); if (faifa == NULL) goto __error_malloc; return faifa; free(faifa); __error_malloc: return NULL; } void faifa_free(faifa_t *faifa) { free(faifa); } char *faifa_error(faifa_t *faifa) { if (faifa) return faifa->error; else return NULL; } int faifa_open(faifa_t *faifa, char *name) { char pcap_errbuf[PCAP_ERRBUF_SIZE]; int pcap_snaplen = ETHER_MAX_LEN; #ifndef __CYGWIN__ if (getuid() > 0) { faifa_set_error(faifa, "Must be root to execute this program"); goto __error_pcap_lookupdev; } if (!pcap_lookupdev(pcap_errbuf)) { faifa_set_error(faifa, "pcap_lookupdev: can't find device %s", name); goto __error_pcap_lookupdev; } /* Use open_live on Unixes */ faifa->pcap = pcap_open_live(name, pcap_snaplen, 1, 100, pcap_errbuf); #else pcap_if_t *alldevs; pcap_if_t *d; pcap_addr_t *a; int i = 0; int inum; if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, pcap_errbuf) == -1) { faifa_set_error(faifa, "Could not get interface list"); goto __error_pcap_lookupdev; } for (d = alldevs; d != NULL; d = d->next) { if (d->flags & PCAP_IF_LOOPBACK) continue; printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" No description\n"); for (a = d->addresses; a; a = a->next) if (a->addr->sa_family != AF_INET) continue; } if (!i) { faifa_set_error(faifa, "No interfaces found"); goto __error_pcap_lookupdev; } __ask_inum: //TODO : remove this user input to an external function to enumerate interfaces rather then inside a library printf("Enter interface number (1-%d):", i); scanf("%d", &inum); if (inum < 1 || inum > i) { printf("Interface index out of range !\n"); goto __ask_inum; } /* Jump to the selected adapter */ for (d = alldevs, i = 0; i < inum-1; d = d->next, i++); strcpy(name, d->name); pcap_snaplen = 65536; printf("Using: %s\n", name); faifa->pcap = pcap_open(name, pcap_snaplen, 1, 1000, NULL, pcap_errbuf); #endif if (faifa->pcap == NULL) { faifa_set_error(faifa, "pcap_open_live: %s", pcap_errbuf); goto __error_pcap_open_live; } if (pcap_datalink(faifa->pcap) != DLT_EN10MB) { faifa_set_error(faifa, "pcap: device %s is not Ethernet", name); goto __error_device_not_ethernet; } /* TODO: Check FreeBSD pcap BIOCIMMEDIATE behavior and compatibility */ #ifdef DARWIN u_int arg = 1; if (ioctl(pcap_fileno(faifa->pcap), BIOCIMMEDIATE, &arg) < 0) faifa_set_error(faifa,"Can not set ioctl BIOCIMMEDIATE in %s", name); #endif strncpy(faifa->ifname, name, sizeof(faifa->ifname)); #ifdef __CYGWIN__ pcap_freealldevs(alldevs); #endif return 0; __error_device_not_ethernet: pcap_close(faifa->pcap); __error_pcap_open_live: __error_pcap_lookupdev: return -1; } int faifa_recv(faifa_t *faifa, void *buf, int len) { struct pcap_pkthdr *pcap_header; u_char *pcap_data; int n; n = pcap_next_ex(faifa->pcap, &pcap_header, (const u_char **)&pcap_data); if (n < 0) { faifa_set_error(faifa, "pcap_next_ex: %s", pcap_geterr(faifa->pcap)); return -1; } if (n == 0 ) return 0; if ((u_int32_t)len > (u_int32_t)(pcap_header->caplen)) len = pcap_header->caplen; memcpy(buf, pcap_data, len); return len; } int faifa_send(faifa_t *faifa, void *buf, int len) { int n; n = pcap_sendpacket(faifa->pcap, buf, len); if (n == -1) { faifa_set_error(faifa, "pcap_inject: %s", pcap_geterr(faifa->pcap)); } return n; } typedef struct faifa_loop_data { faifa_t *faifa; faifa_loop_handler_t handler; void *user; } faifa_loop_data_t; void faifa_loop_handler(faifa_loop_data_t *loop_data, struct pcap_pkthdr *pcap_header, void *pcap_data) { loop_data->handler(loop_data->faifa, pcap_data, pcap_header->caplen, loop_data->user); } int faifa_loop(faifa_t *faifa, faifa_loop_handler_t handler, void *user) { faifa_loop_data_t loop_data = { faifa, handler, user }; int n; n = pcap_loop(faifa->pcap, -1, (void *)faifa_loop_handler, (u_char *)&loop_data); if (n == -1) { faifa_set_error(faifa, "pcap_loop: %s", pcap_geterr(faifa->pcap)); } return n; } int faifa_close(faifa_t *faifa) { pcap_close(faifa->pcap); memset(faifa->ifname, '\0', sizeof(faifa->ifname)); return 0; } int faifa_sprint_hex(char *str, void *buf, int len, char *sep) { int avail = len; u_int8_t *pbuf = buf; char *pstr = str; while (avail > 0) { pstr += sprintf((char *)pstr, "%02hX%s", (unsigned short int)*pbuf, (avail > 1) ? sep : ""); pbuf++; avail--; } return (pstr - str); } #ifdef __IS_THIS_REALLY_NEEDED__ int faifa_get_hwaddr(faifa_t *faifa, u_int8_t *hwaddr) { int fd; struct ifreq ifr; fd = socket(AF_INET, SOCK_DRAM, 0); if (fd == -1) { faifa_set_error(faifa, "socket: %s", strerror(errno)); goto __error_socket; } strncpy(ifr.ifr_name, faifa->ifname, sizeof(ifr.ifr_name) - 1); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { faifa_set_error(faifa, "ioctl: %s", strerror(errno)); goto __error_ioctl; } memcpy(hwaddr, &(ifr.ifr_hwaddr), ETHER_ADDR_LEN); close(fd); return 0; __error_ioctl: close(fd); __error_socket: return -1; } #endif /* __IS_THIS_REALLY_NEEDED__ */ int faifa_parse_mac_addr(faifa_t *faifa, const char *mac, u_int8_t *addr) { int i; long val; if (strlen(mac) != 17) { faifa_set_error(faifa, "macaddr: invalid address length"); return -1; } if (mac[2] != ':' || mac[5] != ':' || mac[8] != ':' || mac[11] != ':' || mac[14] != ':') { faifa_set_error(faifa, "macaddr: invalid format"); return -1; } for (i = 0; i < ETHER_ADDR_LEN; i++) { val = strtol(mac + (3 * i), NULL, 16); addr[i] = val; } return 0; } void faifa_set_dst_addr(faifa_t *faifa, const u_int8_t *addr) { memcpy(faifa->dst_addr, addr, ETHER_ADDR_LEN); } void faifa_set_verbose(faifa_t *faifa, int verbose) { faifa->verbose = verbose; } faifa-0.2~svn82.orig/endian.h0000644000175000017500000000224511562226015015765 0ustar drazzibdrazzib#ifndef __endian_compat_h #define __endian_compat_h #if defined(__linux__) || defined(__GNU__) #include #include_next #elif defined(__APPLE__) #include #include #define bswap_16(x) NXSwapShort(x) #define bswap_32(x) NXSwapInt(x) #define bswap_64(x) NXSwapLongLong(x) #elif defined(__FreeBSD__) #include #define bswap_16(x) bswap16(x) #define bswap_32(x) bswap32(x) #define bswap_64(x) bswap64(x) #else #include #define bswap_16(x) swap16(x) #define bswap_32(x) swap32(x) #define bswap_64(x) swap64(x) #endif #ifndef __BYTE_ORDER #define __BYTE_ORDER BYTE_ORDER #endif #ifndef __BIG_ENDIAN #define __BIG_ENDIAN BIG_ENDIAN #endif #ifndef __LITTLE_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN #endif #if __BYTE_ORDER == __BIG_ENDIAN #define STORE32_LE(X) bswap_32(X) #elif __BYTE_ORDER == __LITTLE_ENDIAN #define STORE32_LE(X) (X) #else #error unkown endianness! #endif #if __BYTE_ORDER == __BIG_ENDIAN #define STORE16_LE(X) bswap_16(X) #elif __BYTE_ORDER == __LITTLE_ENDIAN #define STORE16_LE(X) (X) #else #error unkown endianness! #endif #endif faifa-0.2~svn82.orig/frame.h0000644000175000017500000000402611251165575015630 0ustar drazzibdrazzib/* * Frame operations public interface * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ int ether_init_header(void *buf, int len, u_int8_t *da, u_int8_t *sa, u_int16_t ethertype); int set_init_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, void *user)); int set_dump_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, struct ether_header *hdr)); void do_receive_frame(faifa_t *faifa, void *buf, int len, void *UNUSED(user)); faifa-0.2~svn82.orig/Makefile.in0000644000175000017500000000462011562014143016417 0ustar drazzibdrazzib# # Makefile for the faifa program and library # # # Copyright (C) 2007-2009 # Xavier Carcelle # Florian Fainelli # Nicolas Thill # # License: # GPLv2 # CC = @CC@ STRIP ?= $(CROSS)strip CFLAGS = @CFLAGS@ -Wno-unused-result INSTALL = @INSTALL@ LIBS = @LIBS@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ mandir = @mandir@ libdir = @libdir@ datarootdir = @datarootdir@ includedir = @includedir@ OS?=$(shell uname -s | tr a-z A-Z) APP:=faifa SVN_REV?=$(shell LC_ALL=C svn info | awk '/Revision/ { print $$2 }') # Object files for the library LIB_OBJS:=faifa.o frame.o crypto.o LIB_NAME:=lib$(APP).a LIB_SONAME:=lib$(APP).so.0 # Object files for the program OBJS:= main.o HEADERS:= faifa.h faifa_compat.h faifa_priv.h homeplug.h homeplug_av.h crypto.h device.h endian.h ifeq ($(OS),DARWIN) LDFLAGS:=-dynamiclib -Wl,-dylib_install_name -Wl,$(LIB_SONAME) endif LIBS:=$(LDFLAGS) $(LIBS) ifeq ($(OS),CYGWIN_NT-5.1) LIBS+=-lwpcap APP:=$(APP).exe else CFLAGS+= -fPIC endif man8dir = $(mandir)/man8 # Man page MANTYP=8 MANFIL=$(APP).8.gz all: $(APP) $(LIB_NAME) $(LIB_SONAME) $(APP): $(OBJS) $(HEADERS) $(LIB_SONAME) $(CC) -D$(OS) -DSVN_REV=$(SVN_REV) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(LIB_SONAME) $(LIB_NAME): $(LIB_OBJS) $(HEADERS) $(AR) rcs $(LIB_NAME) $(LIB_OBJS) $(LIB_SONAME): $(LIB_OBJS) $(HEADERS) $(CC) -shared -Wl,-soname,$(LIB_SONAME) -o $(LIB_SONAME) $(LIB_OBJS) $(LIBS) %.o: %.c $(HEADERS) $(CC) -D$(OS) -DSVN_REV=$(SVN_REV) $(CFLAGS) -c $< clean: rm -f $(APP) faifa-dump-devel-stdout \ *.o \ *.a \ *.so* \ $(MANFIL) autoclean: -rm -f configure config.log config.status Makefile distclean: clean autoclean install: installman strip $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m0755 $(APP) $(DESTDIR)$(bindir) $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -m0644 $(LIB_SONAME) $(DESTDIR)$(libdir) $(INSTALL) -d $(DESTDIR)$(includedir)/faifa cp $(HEADERS) $(DESTDIR)$(includedir)/faifa strip: $(STRIP) $(APP) $(STRIP) $(LIB_SONAME) man: -rm -f $(MANFIL) gzip -c -q -9v $(APP).$(MANTYP) > $(MANFIL) installman: man $(INSTALL) -d $(DESTDIR)$(man8dir) $(INSTALL) -m0644 $(MANFIL) $(DESTDIR)$(man8dir) uninstallman: -rm -f $(DESTDIR)$(man8dir)/$(MANFIL) uninstall: uninstallman -rm -f $(DESTDIR)$(bindir)/$(APP) -rm -f $(DESTDIR)$(libdir)/$(LIB_SONAME) -rm -rf $(DESTDIR)$(includedir)/faifa .PHONY: clean faifa-0.2~svn82.orig/homeplug.h0000644000175000017500000001037711251165575016364 0ustar drazzibdrazzib/* * Homeplug 1.0 Ethernet frame definitions * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __HOMEPLUG_H__ #define __HOMEPLUG_H__ #include #define ETHERTYPE_HOMEPLUG 0x887b /** * hp10_mmentry - HomePlug 1.0 MAC Management Entry (MME) * @mmetype: MME type * @mmelength: MME data length * @mmedata: MME data */ struct hp10_mmentry { u_int8_t mmetype:5; u_int8_t mmeversion:3; u_int8_t mmelength; u_int8_t mmedata[0]; } __attribute__((__packed__)); /** * hp10_frame - HomePlug 1.0 frame * @mecount: Number of MAC entries in this frame * @mentries: MAC Entries */ struct hp10_frame { u_int8_t mmecount:7; u_int8_t reserved:1; struct hp10_mmentry mmentries[0]; } __attribute__((__packed__)); /** * hp10_frame_ops - Homeplug 1.0 ethernet frames operations * @mmtype: frame specific MM type * @desc: frame description * @init_frame: frame specific initialisation callback * @dump_frame: frame specific dump callback */ struct hp10_frame_ops { u_int8_t mmtype; char *desc; int (*init_frame)(void *buf, int len, void *user); int (*dump_frame)(void *buf, int len); }; /* 00 - Channel Estimation Request */ struct hp10_channel_estimation_request { u_int8_t reserved1:4; u_int8_t version:4; } __attribute__((__packed__)); /* 08 - Network parameters Confirm */ struct hp10_parameters_stats_confirm { u_int16_t tx_ack_cnt; u_int16_t tx_nack_cnt; u_int16_t tx_fail_cnt; u_int16_t tx_cont_loss_cnt; u_int16_t tx_coll_cnt; u_int16_t tx_ca3_cnt; u_int16_t tx_ca2_cnt; u_int16_t tx_ca1_cnt; u_int16_t tx_ca0_cnt; u_int32_t rx_cumul; } __attribute__((__packed__)); /* 1a - Network statistics Confirm */ struct hp10_tonemap { u_int8_t netw_da[6]; u_int16_t bytes40; u_int16_t fails; u_int16_t drops; } __attribute__((__packed__)); #define HP10_NUM_TONE_MAP 15 /* 1c - Extended network statistics Confirm */ struct hp10_network_stats_confirm { u_int8_t icid:7; u_int8_t ac:1; u_int16_t bytes40_robo; u_int16_t fails_robo; u_int16_t drops_robo; struct hp10_tonemap nstone[HP10_NUM_TONE_MAP]; } __attribute__((__packed__)); /* 1f - Performance statistics confirm */ struct hp10_perf_stats_confirm { u_int8_t rsvd:7; u_int8_t perf_ctrl:1; u_int16_t max_delay; u_int16_t max_delay_jitter_ca[4]; u_int16_t max_latency_ca[4]; u_int16_t max_latency_bin_ca0[10]; u_int16_t max_latency_bin_ca1[10]; u_int16_t max_latency_bin_ca2[10]; u_int16_t max_latency_bin_ca3[10]; u_int16_t rst_cnt; u_int16_t txack; // [31 - 16] u_int16_t txnack; // [31 - 16] u_int16_t txcoll; // [31 - 16] u_int16_t tcloss; // [31 - 16] u_int16_t txcalat[4]; // [31 - 16] u_int16_t rxbp40; //[63 - 32] } __attribute__((__packed__)); #endif /* __INTELLON_H__ */ faifa-0.2~svn82.orig/homeplug_av.h0000644000175000017500000005300311562014704017033 0ustar drazzibdrazzib/* * Homeplug AV Ethernet frame definitions * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __HOMEPLUG_AV_H__ #define __HOMEPLUG_AV_H__ #include #include "faifa_compat.h" #define ETHERTYPE_HOMEPLUG_AV 0x88e1 #define HPAV_VERSION_1_0 0x00 #define HPAV_VERSION_1_1 0x01 #define HPAV_MM_TYPE_MASK 0x0003 #define HPAV_MM_REQUEST 0x0000 #define HPAV_MM_CONFIRM 0x0001 #define HPAV_MM_INDICATE 0x0002 #define HPAV_MM_RESPONSE 0x0003 #define HPAV_MM_CATEGORY_MASK 0xE000 #define HPAV_MM_STA_TO_CCO 0x0000 #define HPAV_MM_ANY_TO_PCO 0x2000 #define HPAV_MM_CCO_TO_CCO 0x4000 #define HPAV_MM_STA_TO_STA 0x6000 #define HPAV_MM_MANUF_SPEC 0x8000 #define HPAV_MM_VENDOR_SPEC 0xA000 #define HPAV_MIN_FRAMSIZ 46 /** * hpav_frame_header - HomePlug AV frame header * @mmver: MM version of the frame * @mmtype: MM type for this frame */ struct hpav_frame_header { u_int8_t mmver; u_int16_t mmtype; } __attribute__((__packed__)); /** * hpav_frame_public_payload - HomePlug AV Public MMEs payload * @data: Frame-Specific data */ struct hpav_frame_public_payload { u_int8_t frag_count:4; u_int8_t frag_index:4; u_int8_t frag_seqnum; u_int8_t data[0]; } __attribute__((__packed__)); /** * hpav_frame_vendor_payload - HomePlug AV Vendor-Specific MMEs payload * @oui: Vendor OUI (Intellon OUI : 0x00, 0xb0, 0x52) * @data: Frame-Specific data */ struct hpav_frame_vendor_payload { u_int8_t oui[3]; u_int8_t data[0]; } __attribute__((__packed__)); /** * hpav_frame - HomePlug AV frame * @header: hpav_frame_header * @public Public variant part * @vendor Vendor-Specific variant part */ struct hpav_frame { struct hpav_frame_header header; union { struct hpav_frame_public_payload public; struct hpav_frame_vendor_payload vendor; } __attribute__((__packed__)) payload; } __attribute__((__packed__)); /** * hpav_frame_ops - Homeplug AV ethernet frames operations * @mmtype: frame specific MM type * @desc: frame description * @init_frame: frame specific initialisation callback * @dump_frame: frame specific dump callback */ struct hpav_frame_ops { u_int16_t mmtype; char *desc; int (*init_frame)(void *buf, int len, void *user); int (*dump_frame)(void *buf, int len, struct ether_header *hdr); }; /* Central Coordination Discover List MME */ struct cc_sta_info { u_int8_t macaddr[6]; u_int8_t tei; u_int8_t same_network; u_int8_t snid; u_int8_t rsvd; u_int8_t cco_cap; u_int8_t sig_level; } __attribute__((__packed__)); struct cc_sta_infos { u_int8_t count; struct cc_sta_info infos[0]; } __attribute__((__packed__)); struct cc_net_info { u_int8_t nid[7]; u_int8_t snid; u_int8_t hybrid_mode; u_int8_t num_bcn_slots; u_int8_t cco_status; u_int16_t bcn_offset; } __attribute__((__packed__)); struct cc_net_infos { u_int8_t count; struct cc_net_info infos[0]; } __attribute__((__packed__)); /* 0014 - CC Discover List Request */ /* 0015 - CC Discover List Confirm */ struct cc_discover_list_confirm { struct cc_sta_infos sta[0]; struct cc_net_infos net[0]; } __attribute__((__packed__)); /* Get Device/SW Version MME */ /* 0xA000 - Get Device/SW Version Request */ /* 0xA001 - Get Device/SW Version Confirm */ struct get_device_sw_version_confirm { u_int8_t mstatus; u_int8_t device_id; u_int8_t version_length; u_int8_t version[64]; u_int8_t upgradeable; } __attribute__((__packed__)); /* Write MAC Memory MME */ /* A004 - Write MAC Memory Request */ struct write_mac_memory_request { u_int32_t address; u_int32_t length; u_int8_t data[0]; } __attribute__((__packed__)); /* A005 - Write MAC Memory Confirm */ struct write_mac_memory_confirm { u_int8_t mstatus; u_int32_t address; u_int32_t length; } __attribute__((__packed__)); /* Read MAC Memory MME */ /* A008 - Read MAC Memory Request */ struct read_mac_memory_request { u_int32_t address; u_int32_t length; } __attribute__((__packed__)); /* A009 - Read MAC Memory Confirm */ struct read_mac_memory_confirm { u_int8_t mstatus; u_int32_t address; u_int32_t length; u_int8_t data[0]; } __attribute__((__packed__)); /* Start MAC MME */ /* Module ID */ enum module_id { MAC_SL_IMG = 0x00, MAC_SW_IMG = 0x01, PIB = 0x02, WR_ALT_FLSH = 0x10, } __attribute__((__packed__)); /* A00C - Start MAC Request */ struct start_mac_request { u_int8_t module_id; u_int8_t reserved1[3]; u_int32_t image_load; u_int32_t image_length; u_int32_t image_chksum; u_int32_t image_saddr; } __attribute__((__packed__)); /* A00D - Start MAC Confirm */ struct start_mac_confirm { u_int8_t mstatus; u_int8_t module_id; } __attribute__((__packed__)); /* Get NVM Parameters MME */ /* A010 - Get NVM Parameters Request */ /* A011 - Get NVM Parameters Confirm */ struct get_nvm_parameters_confirm { u_int8_t mstatus; u_int32_t manuf_code; u_int32_t page_size; u_int32_t block_size; u_int32_t mem_size; } __attribute__((__packed__)); /* Reset Device MME */ /* A01C - Reset Device Request */ /* A01D - Reset Device Confirm */ struct reset_device_confirm { u_int8_t mstatus; } __attribute__((__packed__)); /* Write Module Data MME */ enum write_module_id { SUCCESS = 0x00, INV_MOD_ID = 0x10, BAD_HDR_CHKSUM = 0x18, INV_LEN = 0x1C, UNEX_OFF = 0x20, INV_CHKSUM = 0x14, } __attribute__((__packed__)); /* A020 - Write Module Data Request */ struct write_mod_data_request { u_int8_t module_id; u_int8_t reserved1[1]; u_int16_t length; u_int32_t offset; u_int32_t checksum; u_int8_t data[0]; } __attribute__((__packed__)); /* A021 - Write Module Data Confirm */ struct write_mod_data_confirm { u_int8_t mstatus; u_int8_t module_id; u_int8_t reserved1[1]; u_int16_t length; u_int32_t offset; } __attribute__((__packed__)); /* A022 - Write Module Data Indicate */ struct write_mod_data_indicate { u_int8_t mstatus; u_int8_t module_id; } __attribute__((__packed__)); /* Read Module Data MME */ /* A024 - Read Module Data Request */ struct read_mod_data_request { u_int8_t module_id; u_int8_t reserved1[1]; u_int16_t length; u_int32_t offset; } __attribute__((__packed__)); /* A025 - Read Module Data Confirm */ struct read_mod_data_confirm { u_int8_t mstatus; u_int8_t reserved1[3]; u_int8_t module_id; u_int8_t reserved2[1]; u_int16_t length; u_int32_t offset; u_int32_t checksum; u_int8_t data[0]; } __attribute__((__packed__)); /* Write Module Data to NVM MME */ /* A028 - Write Module Data to NVM Request */ struct write_module_data_to_nvm_request { u_int8_t module_id; } __attribute__((__packed__)); /* A029 - Write Module Data to NVM Confirm */ struct write_module_data_to_nvm_confirm { u_int8_t mstatus; u_int8_t module_id; } __attribute__((__packed__)); /* Get Watchdog Report MME */ /* A02C - Get Watchdog Report Request */ struct get_watchdog_report_request { u_int16_t session_id; u_int8_t clr_flag; } __attribute__((__packed__)); /* A02E - Get Watchdog Report Indicate */ struct get_watchdog_report_indicate { u_int8_t mstatus; u_int16_t session_id; u_int8_t num_parts; u_int8_t cur_part; u_int16_t data_length; u_int8_t data_offset; u_int8_t data[0]; } __attribute__((__packed__)); /* Link Statistics MME */ /* Status types */ enum statistics_status { HPAV_SUC = 0x00, HPAV_INV_CTL = 0x01, HPAV_INV_DIR = 0x02, HPAV_INV_LID = 0x10, HPAV_INV_MAC = 0x20, }; /* Direction types */ enum statistics_direction { HPAV_SD_TX = 0x00, HPAV_SD_RX = 0x01, HPAV_SD_BOTH = 0x02, }; enum link_id { HPAV_LID_CSMA_CAP_0 = 0x00, HPAV_LID_CSMA_CAP_1 = 0x01, HPAV_LID_CSMA_CAP_2 = 0x02, HPAV_LID_CSMA_CAP_3 = 0x03, HPAV_LID_CSMA_SUM = 0xF8, HPAV_LID_CSMA_SUM_ANY = 0xFC, }; struct rx_interval_stats { u_int8_t phyrate; u_int64_t pb_passed; u_int64_t pb_failed; u_int64_t tbe_passed; u_int64_t tbe_failed; } __attribute__((__packed__)); struct tx_link_stats { u_int64_t mpdu_ack; u_int64_t mpdu_coll; u_int64_t mpdu_fail; u_int64_t pb_passed; u_int64_t pb_failed; } __attribute__((__packed__)); struct rx_link_stats { u_int64_t mpdu_ack; u_int64_t mpdu_fail; u_int64_t pb_passed; u_int64_t pb_failed; u_int64_t tbe_passed; u_int64_t tbe_failed; u_int8_t num_rx_intervals; struct rx_interval_stats rx_interval_stats[0]; } __attribute__((__packed__)); /* A030 - Link Statistics Request */ struct link_statistics_request { u_int8_t control; u_int8_t direction; u_int8_t link_id; u_int8_t macaddr[6]; } __attribute__((__packed__)); /* A031 - Link Statistics Confirm */ struct link_statistics_confirm { u_int8_t mstatus; u_int8_t direction; u_int8_t link_id; u_int8_t tei; union { struct tx_link_stats tx; struct rx_link_stats rx; struct { struct tx_link_stats tx; struct rx_link_stats rx; } __attribute__((__packed__)) both; } __attribute__((__packed__)); } __attribute__((__packed__)); /* Sniffer MME */ /* Sniffer Control */ enum sniffer_control { HPAV_SC_DISABLE = 0x00, HPAV_SC_ENABLE = 0x01, HPAV_SC_NO_CHANGE = 0x02, }; enum sniffer_state { HPAV_ST_DISABLED = 0x00, HPAV_ST_ENABLED = 0x01, }; struct hpav_fc { u_int8_t del_type:3; u_int8_t access:1; u_int8_t snid:4; u_int8_t stei; u_int8_t dtei; u_int8_t lid; u_int8_t cfs:1; u_int8_t bdf:1; u_int8_t hp10df:1; u_int8_t hp11df:1; u_int8_t eks:4; u_int8_t ppb; u_int8_t ble; u_int8_t pbsz:1; u_int8_t num_sym:2; u_int8_t tmi_av:5; u_int16_t fl_av:12; u_int8_t mpdu_cnt:2; u_int8_t burst_cnt:2; u_int8_t clst:3; u_int8_t rg_len_lo:5; u_int8_t rg_len_hi:1; u_int8_t mfs_cmd_mgmt:3; u_int8_t mfs_cmd_data:3; u_int8_t rsr:1; u_int8_t mcf:1; u_int8_t dccpcf:1; u_int8_t mnbf:1; u_int8_t rsvd:5; u_int8_t fccs_av[3]; } __attribute__((__packed__)); struct hpav_bcn { u_int8_t del_type:3; u_int8_t access:1; u_int8_t snid:4; u_int32_t bts; u_int16_t bto_0; u_int16_t bto_1; u_int16_t bto_2; u_int16_t bto_3; u_int8_t fccs_av[3]; } __attribute__((__packed__)); /* 0xA034 - Sniffer Request */ struct sniffer_request { u_int8_t control; u_int8_t reserved1[4]; } __attribute__((__packed__)); /* 0xA035 - Sniffer Confirm */ struct sniffer_confirm { u_int8_t mstatus; u_int8_t state; u_int8_t da[6]; } __attribute__((__packed__)); /* 0xA036 - Sniffer Indicate */ struct sniffer_indicate { u_int8_t type; u_int8_t direction; u_int64_t systime; u_int32_t beacontime; struct hpav_fc fc; struct hpav_bcn bcn; } __attribute__((__packed__)); /* Network Info MME */ enum sta_role { HPAV_SR_STA = 0x00, HPAV_SR_PROXY = 0x01, HPAV_SR_CCO = 0x02, }; struct sta_info { u_int8_t sta_macaddr[6]; u_int8_t sta_tei; u_int8_t bridge_macaddr[6]; u_int8_t avg_phy_tx_rate; u_int8_t avg_phy_rx_rate; } __attribute__((__packed__)); /* 0xA038 - Network Info Request */ /* 0xA039 - Network Info Confirm */ struct network_info_confirm { u_int8_t num_avlns; u_int8_t nid[7]; u_int8_t snid; u_int8_t tei; u_int8_t sta_role; u_int8_t cco_macaddr[6]; u_int8_t cco_tei; u_int8_t num_stas; struct sta_info stas[0]; } __attribute__((__packed__)); /* Check Points MME */ /* A040 - Check Points Request */ struct check_points_request { u_int16_t session_id; u_int8_t clr_flag; } __attribute__((__packed__)); /* A042 - Check Points Indicate */ struct check_points_indicate { u_int8_t mstatus:3; u_int8_t major:1; u_int8_t buf_locked:1; u_int8_t auto_lock:1; u_int8_t unsoc_upd:1; u_int8_t unsoc:1; u_int8_t reserved1[14]; u_int16_t session_id; u_int32_t length; u_int32_t offset; u_int32_t index; u_int8_t num_parts; u_int8_t cur_part; u_int16_t data_length; u_int16_t data_offset; u_int8_t data[0]; } __attribute__((__packed__)); /* Loopback MME */ /* A048 - Loopback Request */ struct loopback_request { u_int8_t duration; u_int8_t reserved1[0]; u_int16_t length; u_int8_t data[0]; } __attribute__((__packed__)); /* A049 - Loopback Confirm */ struct loopback_confirm { u_int8_t mstatus; u_int8_t duration; u_int16_t length; } __attribute__((__packed__)); /* Loopback Status MME */ /* A04C - Loopback Status Request */ /* A04D - Loopback Status Confirm */ struct loopback_status_confirm { u_int8_t mstatus; u_int8_t state; } __attribute__((__packed__)); /* Set Encryption Key MME */ enum set_enc_key_status { KEY_SUCCESS = 0x00, KEY_INV_EKS = 0x10, KEY_INV_PKS = 0x11, KEY_UKN = 0x12, }; #define AES_KEY_SIZE 16 /* A050 - Set Encryption Key Request */ struct set_encryption_key_request { u_int8_t peks; u_int8_t nmk[AES_KEY_SIZE]; u_int8_t peks_payload; u_int8_t rdra[6]; u_int8_t nmk_payload[AES_KEY_SIZE]; } __attribute__((__packed__)); /* A051 - Set Encryption Key Confirm */ struct set_encryption_key_confirm { u_int8_t mstatus; }; /* Get Manufacturing String MME */ /* A054 - Get Manufacturing String Request */ /* A055 - Get Manufacturing String Confirm */ struct get_manuf_string_confirm { u_int8_t status; u_int8_t length; u_int8_t data[64]; } __attribute__((__packed__)); /* Read Configuration Block & SDRAM Configuration MME */ enum sdram_status { SDR_INV_CHKSUM = 0x30, SDR_BIST_FAILED = 0x34, }; struct sdram_config { u_int32_t size; u_int32_t conf_reg; u_int32_t timing0; u_int32_t timing1; u_int32_t ctl_reg; u_int32_t ref_reg; u_int32_t clk_reg_val; u_int32_t reserved; } __attribute__ ((__packed__)); struct block_header { u_int32_t version; u_int32_t img_rom_addr; u_int32_t img_sdram_addr; u_int32_t img_length; u_int32_t img_checksum; u_int32_t entry_point; u_int8_t reserved[12]; u_int32_t next_header; u_int32_t hdr_checksum; } __attribute__((__packed__)); /* A058 - Read Configuration Block Request */ /* A059 - Read Configuration Block Confirm */ struct read_config_block_confirm { u_int8_t mstatus; u_int8_t config_length; struct block_header hdr; struct sdram_config config; } __attribute__((__packed__)); /* A05C - Set SDRAM Configuration Request */ struct set_sdram_config_request { struct sdram_config config; u_int32_t checksum; } __attribute__((__packed__)); /* A05D - Set SDRAM Configuration Confirm */ struct set_sdram_config_confirm { u_int8_t mstatus; } __attribute__((__packed__)); /* Embedded Host Action Required MME */ enum host_actions { LOADER = 0x00, FIRM_UP_RDY = 0x01, PIB_UP_RDY = 0x02, FIRM_UP_PIB_RDY = 0x03, LOADER_SDR_RDY = 0x04, }; /* A062 - Embedded Host Action Required Indicate */ struct embedded_host_action_indicate { u_int8_t action; } __attribute__((__packed__)); /* A063 - Embedded Host Action Required Response */ struct embedded_host_action_response { u_int8_t mstatus; } __attribute__((__packed__)); /* Get Devices Attributes MME */ struct get_devices_attrs_fmt { u_int8_t hardware[16]; u_int8_t software[16]; u_int32_t major; u_int32_t minor; u_int32_t subversion; u_int32_t build_number; u_int8_t rsvd[8]; u_int8_t build_date[8]; u_int8_t release_type[12]; } __attribute__((__packed__)); /* A068 - Get Devices Attributes Request */ struct get_devices_attrs_request { u_int32_t cookie; u_int8_t rtype; } __attribute__((__packed__)); /* A069 - Get Devices Attributes Confirm */ struct get_devices_attrs_confirm { u_int16_t status; u_int32_t cookie; u_int8_t rtype; u_int16_t size; struct get_devices_attrs_fmt fmt; } __attribute__((__packed__)); /* Ethernet PHY Settings MME */ enum enet_speed { ENET = 0x00, FA_ENET = 0x01, GIG_ENET = 0x02, }; /* AO6C - Get Ethernet PHY Settings Request */ struct get_enet_phy_settings_request { u_int8_t mcontrol; u_int8_t addcaps; u_int8_t reserved[3]; } __attribute__((__packed__)); /* AO6D - Get Ethernet PHY Settings Confirm */ struct get_enet_phy_settings_confirm { u_int8_t status; u_int8_t speed; u_int8_t duplex; } __attribute__((__packed__)); /* Tone Map Characteristics MME */ /* Various carrier modulations */ enum mod_carrier { NO = 0x0, BPSK = 0x1, QPSK = 0x2, QAM_8 = 0x3, QAM_16 = 0x4, QAM_64 = 0x5, QAM_256 = 0x6, QAM_1024 = 0x7, }; struct modulation_stats { unsigned no; unsigned bpsk; unsigned qpsk; unsigned qam8; unsigned qam16; unsigned qam64; unsigned qam256; unsigned qam1024; unsigned unknown; }; /* Statistics group two carrier on 4 bits */ struct carrier { u_int8_t mod_carrier_lo:4; u_int8_t mod_carrier_hi:4; } __attribute__((__packed__)); #define MAX_CARRIERS (1156 / 2) /* A070 - Tone Map Characteristics Request */ struct get_tone_map_charac_request { u_int8_t macaddr[6]; u_int8_t tmslot; } __attribute__((__packed__)); /* A071 - Tone Map Characteristics Confirm */ struct get_tone_map_charac_confirm { u_int8_t mstatus; u_int8_t tmslot; u_int8_t num_tms; u_int16_t tm_num_act_carrier; struct carrier carriers[MAX_CARRIERS]; } __attribute__((__packed__)); /* Encrypted Payload MME */ enum peks_val { DST_STA_DAK = 0x00, NMK_KNOWN_STA = 0x01, ID_TEKS = 0x02, /* to OxE */ NO_KEY = 0x0F, }; enum avln_status { UN_ASSOC_LVL_0 = 0x00, UN_ASSOC_LVL_1 = 0x01, UN_ASSOC_LVL_2 = 0x02, UN_ASSOC_LVL_3 = 0x03, UN_ASSOC_NPCO = 0x04, UN_ASSOC_PCO = 0x05, CCO_AVLN = 0x08, }; enum pid { AUTH_REQ_NEW = 0x00, PROV_STA_NEW = 0x01, PROV_STA_DAK = 0x02, PROV_STA_UKE = 0x03, HLE_PROTO = 0x04, }; struct cm_enc_payload_mm { u_int16_t len; u_int8_t mme[0]; } __attribute__((__packed__)); struct cm_enc_payload_hle_payload { u_int16_t len; u_int8_t random_filler[0]; u_int8_t payload; u_int32_t crc; u_int8_t pid; u_int8_t prn; u_int8_t pmn; u_int8_t padding[0]; u_int8_t rf_len[0]; } __attribute__((__packed__)); /* 6004 - Encrypted Payload Indicate */ struct cm_enc_payload_indicate { u_int8_t peks; u_int8_t avln_status; u_int8_t pid; u_int8_t prn; u_int8_t pmn; u_int8_t aes_iv_uuid[AES_KEY_SIZE]; union { struct cm_enc_payload_mm mm; struct cm_enc_payload_hle_payload payload; } __attribute__((__packed__)); } __attribute__((__packed__)); /* 6005 - Encrypted Payload Response */ struct cm_enc_payload_response { u_int8_t result; u_int8_t pid; u_int16_t prn; } __attribute__((__packed__)); /* Set Key MME */ enum key_type { DAK_AES_128 = 0x00, NMK_AES_128 = 0x01, NEK_AES_128 = 0x02, TEK_AES_128 = 0x03, HASH_KEY = 0x04, NONCE_ONLY = 0x05, }; /* 6008 - Set Key Request */ struct cm_set_key_request { u_int8_t key_type; u_int32_t my_nonce; u_int32_t your_nonce; u_int8_t pid; u_int16_t prn; u_int8_t pmn; u_int8_t cco_cap; u_int8_t nid[7]; u_int8_t new_eks; u_int8_t new_key[0]; /* or AES_KEY_SIZE */ } __attribute__((__packed__)); /* 6009 - Set Key Confirm */ struct cm_set_key_confirm { u_int8_t result; u_int32_t my_nonce; u_int32_t your_nonce; u_int8_t pid; u_int16_t prn; u_int8_t pmn; u_int8_t cco_cap; } __attribute__((__packed__)); /* Get Key MME */ /* 600C - Get Key Request */ struct cm_get_key_request { u_int8_t req_type; u_int8_t req_key_type; u_int8_t nid[7]; u_int32_t my_nonce; u_int8_t pid; u_int16_t prn; u_int8_t pmn; u_int8_t hash_key[0]; } __attribute__((__packed__)); /* 600D - Get Key Confirm */ struct cm_get_key_confirm { u_int8_t result; u_int8_t req_key_type; u_int32_t my_nonce; u_int32_t your_nonce; u_int8_t nid[7]; u_int8_t eks; u_int8_t pid; u_int16_t prn; u_int8_t pmn; u_int8_t key[0]; } __attribute__((__packed__)); /* Get Bridge Infos MME */ struct bridge_infos { u_int8_t btei; u_int8_t nbda; u_int8_t bri_addr[0][6]; }; /* 6020 - Get Bridge Infos Request */ /* 6021 - Get Bridge Infos Confirm */ struct cm_brigde_infos_confirm { u_int8_t bsf; union { struct bridge_infos bridge_infos; } __attribute__((__packed__)); } __attribute__((__packed__)); /* Get Network Infos MME */ struct cm_net_info { u_int8_t nid[7]; u_int8_t snid; u_int8_t tei; u_int8_t sta_role; u_int8_t macaddr[6]; u_int8_t access; u_int8_t num_cord; } __attribute__((__packed__)); struct cm_net_infos { u_int8_t count; struct cm_net_info infos[0]; } __attribute__((__packed__)); /* 6038 - Get Network Infos Request */ /* 6039 - Get Network Infos Confirm */ struct cm_get_network_infos_confirm { struct cm_net_infos net; } __attribute__((__packed__)); /* Get Network Stats MME */ struct cm_sta_info { u_int8_t macaddr[6]; u_int8_t avg_phy_dr_tx; u_int8_t avg_phy_dr_rx; } __attribute__((__packed__)); struct cm_sta_infos { u_int8_t count; struct cm_sta_info infos[0]; } __attribute__((__packed__)); /* 6048 - Get Network Stats Request */ /* 6049 - Get Network Stats Confirm */ struct cm_get_network_stats_confirm { struct cm_sta_infos sta; } __attribute__((__packed__)); #endif /* __HOMEPLUG_AV_H__ */ faifa-0.2~svn82.orig/device.h0000644000175000017500000000462211251165575015777 0ustar drazzibdrazzib/* * Homeplug 1.0/AV device definitions * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __HPAV_DEVICE_H__ #define __HPAV_DEVICE_H__ #include #include "homeplug_av.h" extern int dump_hex(void *buf, int len, char *sep); /** * hpav_device - structure which contains useful device informations * @name: name of the device * @macaddr: MAC address of the device * @role: role of the device in the HomePlug AV network * @sw_version: version of the software running on it * @next: pointer to a hpav_device structure */ struct hpav_device { char *name; /* Device name, if any */ u_int8_t macaddr[6]; /* MAC address of the device */ enum sta_role role; /* Device role in the network */ char *sw_version; /* Software version of the device */ struct hpav_device *next; }; #endif /* __HPAV_DEVICE_H__ */ faifa-0.2~svn82.orig/crc32.h0000644000175000017500000000653711131145474015454 0ustar drazzibdrazzibstatic const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; #define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) uint32_t crc32buf(char *buf, size_t len) { uint32_t crc; crc = 0xFFFFFFFF; for ( ; len; --len, ++buf) { crc = UPDC32(*buf, crc); } return crc; } faifa-0.2~svn82.orig/copyright0000644000175000017500000000712211251226102016300 0ustar drazzibdrazzibThis package was debianized by Florian Fainelli on Sun, 18 May 2008 11:29:24 +0200. It was downloaded from https://dev.open-plc.org Upstream Author: Xavier Carcelle Nicolas Thill Florian Fainelli Copyright: Copyright (C) 2007-2008 Xavier Carcelle Florian Fainelli Nicolas Thill License: GPL (v2 or later) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but is provided AS IS, WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and NON-INFRINGEMENT. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. Certain source files in this program permit linking with the OpenSSL library (http://www.openssl.org), which otherwise wouldn't be allowed under the GPL. For purposes of identifying OpenSSL, most source files giving this permission limit it to versions of OpenSSL having a license identical to that listed in this file (LICENSE.OpenSSL). It is not necessary for the copyright years to match between this file and the OpenSSL version in question. However, note that because this file is an extension of the license statements of these source files, this file may not be changed except with permission from all copyright holders of source files in this program which reference this file. On Debian system the full text of the GPL V2, can be found in `/usr/share/common-licenses/GPL-2'. The Debian packaging is Copyright (C) 2008, Florian Fainelli Copyright (C) 2009, Damien Raude-Morvan and is licensed under the GPL V2 or later, see `/usr/share/common-licenses/GPL-2'. faifa-0.2~svn82.orig/aclocal.m40000644000175000017500000000203611270073556016222 0ustar drazzibdrazzibdnl -------------------------------------------------------------------------- dnl PA_ADD_CFLAGS() dnl dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation dnl -------------------------------------------------------------------------- AC_DEFUN(PA_ADD_CFLAGS, [AC_MSG_CHECKING([if $CC accepts $1]) pa_add_cflags__old_cflags="$CFLAGS" CFLAGS="$CFLAGS $1" AC_TRY_LINK([#include ], [printf("Hello, World!\n");], AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]) CFLAGS="$pa_add_cflags__old_cflags")]) dnl ------------------------------------------------------------------------ dnl PA_WITH_BOOL dnl dnl PA_WITH_BOOL(option, default, help, enable, disable) dnl dnl Provides a more convenient way to specify --with-option and dnl --without-option, with a default. default should be either 0 or 1. dnl ------------------------------------------------------------------------ AC_DEFUN(PA_WITH_BOOL, [AC_ARG_WITH([$1], [$3], if test ["$withval"] != no; then [$4] else [$5] fi, if test [$2] -ne 0; then [$4] else [$5] fi)]) faifa-0.2~svn82.orig/autogen.sh0000755000175000017500000000007011270073556016357 0ustar drazzibdrazzib#!/bin/sh -xe autoheader autoconf rm -rf autom4te.cache faifa-0.2~svn82.orig/COPYING0000644000175000017500000004320511146750441015415 0ustar drazzibdrazzib---------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. faifa-0.2~svn82.orig/crypto.h0000644000175000017500000000505011355357670016060 0ustar drazzibdrazzib/* * Cryptographic headers * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __CRYPTO_H__ #define __CRYPTO_H__ #include #define MAX_SECRET_SIZ 64 #define SALT_SIZ 8 extern u_int8_t dak_salt[SALT_SIZ]; extern u_int8_t nmk_salt[SALT_SIZ]; /** * salted_secret * @len: lenght of the salted secret * @value: value of the salted secret */ struct salted_secret { u_int8_t len; u_int8_t value[72]; }; /** * sha256_ctx * @total: total of the sha256 context * @state: state of the context * @buffer: buffer to calculate stuff */ struct sha256_ctx { u_int32_t total[2]; u_int32_t state[8]; u_int8_t buffer[MAX_SECRET_SIZ]; }; /** * gen_passphrase - create a hash from a user input passphrase * @password: user input password * @key: resulting key * @salt: salt type (NMK, DAK or NID) * @return * 0 on success, -1 on failure */ extern int gen_passphrase(const char *password, u_int8_t *key, const unsigned char *salt); #endif /* __CRYPTO_H__ */ faifa-0.2~svn82.orig/frame.c0000644000175000017500000023656611562226015015633 0ustar drazzibdrazzib/* * Homeplug 1.0/AV Ethernet frame handling and operations * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #ifndef __CYGWIN__ #include #endif #include #include #include #include #include #include "faifa.h" #include "faifa_compat.h" #include "faifa_priv.h" #include "frame.h" #include "homeplug.h" #include "homeplug_av.h" #include "crypto.h" #include "endian.h" #include "crypto.h" #include "crc32.h" FILE *err_stream; FILE *out_stream; FILE *in_stream; /* Constants */ static u_int8_t hpav_intellon_oui[3] = { 0x00, 0xB0, 0x52}; static u_int8_t hpav_intellon_macaddr[ETHER_ADDR_LEN] = { 0x00, 0xB0, 0x52, 0x00, 0x00, 0x01 }; static u_int8_t broadcast_macaddr[ETHER_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /** * init_hex - initialize a buffer using hexadecimal parsing (%2hx) * @buf: buffer to initialize * @len: length of the buffer (sizeof(buf)) */ static int init_hex(void *buf, int len) { int avail = len; u_int8_t *p = buf; while (avail > 0) { if (fscanf(in_stream, "%2hx", (short unsigned int *)p) <= 0) break; p++; avail--; } return (len - avail); } /** * dump_hex - dump a buffer using the hexadecimal conversion (%02hX) * @buf: buffer to dump the content * @len: length of the buffer (sizeof(buf)) * @sep: optional separator, defaults to empty */ int dump_hex(void *buf, int len, char *sep) { int avail = len; u_int8_t *p = buf; while (avail > 0) { faifa_printf(out_stream, "%02hX%s", *p, (avail > 1) ? sep : ""); p++; avail--; } return len; } #define HEX_BLOB_BYTES_PER_ROW 16 static u_int32_t dump_hex_blob(faifa_t *UNUSED(faifa), u_int8_t *buf, u_int32_t len) { u_int32_t i, d, m = len % HEX_BLOB_BYTES_PER_ROW; faifa_printf(out_stream, "Binary Data, %lu bytes", (unsigned long int)len); for (i = 0; i < len; i += HEX_BLOB_BYTES_PER_ROW) { d = (len - i) / HEX_BLOB_BYTES_PER_ROW; faifa_printf(out_stream, "\n%08lu: ", (unsigned long int)i); dump_hex((u_int8_t *)buf + i, (d > 0) ? HEX_BLOB_BYTES_PER_ROW : m, " "); } faifa_printf(out_stream, "\n"); return len; } /** * init_empty_frame - do nothing to a frame * @buf: unused * @len: unused */ static int init_empty_frame(void *UNUSED(buf), int UNUSED(len), void *UNUSED(user)) { return 0; } /* * The following functions are not documented and are faifa internal * operations. They should never be called from outside do_frame or * do_receive_frame because the of generic buffer handling. * * These functions are called as generic callbacks to a corresponding * request, confirmation, indication or response. */ static int hpav_init_write_mac_memory_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct write_mac_memory_request *mm = buf; faifa_printf(out_stream, "Address? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->address)); faifa_printf(out_stream, "Length? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->length)); avail -= sizeof(*mm); faifa_printf(out_stream, "Data?\n"); avail -= init_hex(mm->data, mm->length); return (len - avail); } static int hpav_dump_get_device_sw_version_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_device_sw_version_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); faifa_printf(out_stream, "Device ID: %s, Version: %s, upgradeable: %d\n", (short unsigned int)(mm->device_id) ? "INT6300" : "INT6000" , (char *)(mm->version), (int)(mm->upgradeable)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_write_mac_memory_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct write_mac_memory_request *mm = buf; faifa_printf(out_stream, "Address: 0x%08lx\n", (long unsigned int)(mm->address)); faifa_printf(out_stream, "Length: 0x%08lx\n", (long unsigned int)(mm->length)); avail -= sizeof(*mm); faifa_printf(out_stream, "Data: "); avail -= dump_hex(mm->data, mm->length, " "); faifa_printf(out_stream, "\n"); return (len - avail); } static int hpav_dump_write_mac_memory_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct write_mac_memory_confirm *mm = buf; switch (mm->mstatus) { case 0x00: faifa_printf(out_stream, "Status: Succes\n"); break; case 0x10: faifa_printf(out_stream, "Status: Invalid address\n"); goto out; break; case 0x14: faifa_printf(out_stream, "Status: Invalid length\n"); goto out; break; } faifa_printf(out_stream, "Address: 0x%08lx\n", (long unsigned int)(mm->address)); faifa_printf(out_stream, "Length: 0x%08lx\n", (long unsigned int)(mm->length)); out: avail -= sizeof(*mm); return (len - avail); } static int hpav_init_read_mac_memory_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct read_mac_memory_request *mm = buf; faifa_printf(out_stream, "Address? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->address)); faifa_printf(out_stream, "Length? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->length)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_read_mac_memory_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct read_mac_memory_confirm *mm = buf; faifa_printf(out_stream, "Address: 0x%08lx\n", (long unsigned int)(mm->address)); faifa_printf(out_stream, "Length: %lu (0x%08lx)\n", (long unsigned int)(mm->length), (long unsigned int)(mm->length)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_read_mac_memory_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct read_mac_memory_confirm *mm = buf; switch (mm->mstatus) { case 0x00: faifa_printf(out_stream, "Status: Succes\n"); break; case 0x10: faifa_printf(out_stream, "Status: Invalid address\n"); goto out; break; case 0x14: faifa_printf(out_stream, "Status: Invalid length\n"); goto out; break; } faifa_printf(out_stream, "Address: 0x%08lx\n", (long unsigned int)(mm->address)); faifa_printf(out_stream, "Length: %lu (0x%08lx)\n", (long unsigned int)(mm->length), (long unsigned int)(mm->length)); faifa_printf(out_stream, "Data: "); avail -= dump_hex(mm->data, mm->length, " "); faifa_printf(out_stream, "\n"); out: avail -= sizeof(*mm); return (len - avail); } static char *get_signal_level_str(u_int8_t sig_level) { switch (sig_level) { case 0x00: return "N/A"; break; case 0x01: return "> - 10 dB, but <= 0 dB"; break; case 0x02: return "> - 15 dB, but <= -10 dB"; break; case 0x03: return "> - 20 dB, but <= -15 dB"; break; case 0x04: return "> - 25 dB, but <= -20 dB"; break; case 0x05: return "> - 30 dB, but <= -25 dB"; break; case 0x06: return "> - 35 dB, but <= -30 dB"; break; case 0x07: return "> - 40 dB, but <= -35 dB"; break; case 0x08: return "> - 45 dB, but <= -40 dB"; break; case 0x09: return "> - 50 dB, but <= -45 dB"; break; case 0x0A: return "> - 55 dB, but <= -50 dB"; break; case 0x0B: return "> - 60 dB, but <= -55 dB"; break; case 0x0C: return "> - 65 dB, but <= -60 dB"; break; case 0x0D: return "> - 70 dB, but <= -65 dB"; break; case 0x0E: return "> - 75 dB, but <= -70 dB"; break; case 0x0F: return "<= -75 dB"; break; default: return "Unknown"; break; } return NULL; } static void dump_cc_sta_info(struct cc_sta_info *sta_info) { faifa_printf(out_stream, "MAC address: "); dump_hex(sta_info->macaddr, 6, ":"); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "TEI: %d\n", sta_info->tei); faifa_printf(out_stream, "Same network: %s\n", sta_info->same_network ? "Yes" : "No"); faifa_printf(out_stream, "SNID: %d\n", sta_info->snid); faifa_printf(out_stream, "CCo caps: %02hx\n", (short unsigned int)(sta_info->cco_cap)); faifa_printf(out_stream, "Signal Level: %s\n", get_signal_level_str(sta_info->sig_level)); } static char *get_cco_status_str(u_int8_t status) { switch (status) { case 0x00: return "Unknown"; break; case 0x01: return "Non-Coordinating network"; break; case 0x02: return "Coordinating, group status unknown"; break; case 0x03: return "Coordinating network, same group as CCo"; break; case 0x04: return "Coordinating network, not same group as CCo"; break; default: return "Unknown"; break; } return NULL; } static void dump_cc_net_info(struct cc_net_info *net_info) { faifa_printf(out_stream, "Network ID: "); dump_hex(net_info->nid, sizeof(net_info->nid), " "); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "SNID: %d\n", net_info->snid); faifa_printf(out_stream, "Hybrid mode: %d\n", net_info->hybrid_mode); faifa_printf(out_stream, "Number of BCN slots: %d\n", net_info->num_bcn_slots); faifa_printf(out_stream, "CCo status: %s\n", get_cco_status_str(net_info->cco_status)); faifa_printf(out_stream, "Beacon offset: %04hx\n", (unsigned int)(net_info->bcn_offset)); } static int hpav_dump_cc_discover_list_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cc_discover_list_confirm *mm = buf; struct cc_sta_infos *sta = (struct cc_sta_infos *)&(mm->sta); struct cc_net_infos *net = (struct cc_net_infos *)&(sta->infos[sta->count]); int i; faifa_printf(out_stream, "Number of Stations: %d\n", sta->count); avail -= sizeof(*sta); for (i = 0; i < sta->count; i++) { dump_cc_sta_info(&(sta->infos[i])); avail -= sizeof(sta->infos[i]); } faifa_printf(out_stream, "Number of Networks: %d\n", net->count); avail -= sizeof(*net); for (i = 0; i < net->count; i++) { dump_cc_net_info(&(net->infos[i])); avail -= sizeof(net->infos[i]); } return (len - avail); } static int hpav_init_start_mac_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct start_mac_request *mm = buf; faifa_printf(out_stream, "Module ID? "); fscanf(in_stream, "%2hx", (short unsigned int *)&(mm->module_id)); faifa_printf(out_stream, "Image load address? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->image_load)); faifa_printf(out_stream, "Image length? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->image_length)); faifa_printf(out_stream, "Image checksum? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->image_chksum)); faifa_printf(out_stream, "Image start address? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->image_saddr)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_start_mac_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct start_mac_request *mm = buf; faifa_printf(out_stream, "Module ID: %02hx\n", (short unsigned int)(mm->module_id)); faifa_printf(out_stream, "Image load address: %08lx\n", (long unsigned int)(mm->image_load)); faifa_printf(out_stream, "Image length: %lu (0x%08lx)\n", (long unsigned int)(mm->image_length), (long unsigned int)(mm->image_length)); faifa_printf(out_stream, "Image checksum: %08lx\n", (long unsigned int)(mm->image_chksum)); faifa_printf(out_stream, "Image start address: %08lx\n", (long unsigned int)(mm->image_saddr)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_start_mac_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct start_mac_confirm *mm = buf; switch (mm->mstatus) { case 0x00: faifa_printf(out_stream, "Status: Success\n"); break; case 0x10: faifa_printf(out_stream, "Status: Invalid module ID\n"); goto out; break; case 0x14: faifa_printf(out_stream, "Status: NVM not present\n"); goto out; break; case 0x18: faifa_printf(out_stream, "Status: NVM too small\n"); goto out; break; case 0x1C: faifa_printf(out_stream, "Status: Invalid header checksum\n"); goto out; break; case 0x20: faifa_printf(out_stream, "Status: Invalid section checksum\n"); goto out; break; } faifa_printf(out_stream, "Module ID: %02hx\n", (short unsigned int)(mm->module_id)); out: avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_nvram_params_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_nvm_parameters_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "NVRAM not present" : "Success"); faifa_printf(out_stream, "Manufacturer code: %08lx\n", (long unsigned int)(mm->manuf_code)); faifa_printf(out_stream, "Page size: %lu (0x%08lx)\n", (long unsigned int)(mm->page_size), (long unsigned int)(mm->page_size)); faifa_printf(out_stream, "Block size: %lu (0x%08lx)\n", (long unsigned int)(mm->block_size), (long unsigned int)(mm->block_size)); faifa_printf(out_stream, "Memory size: %lu (0x%08lx)\n", (long unsigned int)(mm->mem_size), (long unsigned int)(mm->mem_size)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_reset_device_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct reset_device_confirm *mm = buf; faifa_printf(out_stream, "Status : %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_write_data_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct write_mod_data_request *mm = buf; char filename[256]; char *buffer; FILE *fp; short unsigned int size; uint32_t crc32; faifa_printf(out_stream, "Module ID? "); fscanf(in_stream, "%2hx", (short unsigned int *)&(mm->module_id)); faifa_printf(out_stream, "Offset? "); fscanf(in_stream, "%8lx", (long unsigned int *)&(mm->offset)); faifa_printf(out_stream, "Firmware file? "); fscanf(in_stream, "%s", (char *)filename); fp = fopen(filename, "rb"); if (!fp) { faifa_printf(err_stream, "Cannot open: %s\n", filename); avail = -1; goto out; } fseek(fp, 0, SEEK_END); size = ftell(fp); if (size > 1024) { faifa_printf(out_stream, "Invalid file size > 1024\n"); avail = -1; goto out; } fseek(fp, 0, SEEK_SET); mm->length = size; buffer = malloc(size); if (!buffer) { faifa_printf(err_stream, "Cannot allocate memory\n"); avail = -1; goto out; } fread(buffer, size, 1, fp); /* Compute crc on the file */ crc32 = crc32buf(buffer, size); memcpy(&(mm->data), buffer, size); mm->checksum = crc32; out: if (fp) fclose(fp); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_write_mod_data_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct write_mod_data_confirm *mm =(struct write_mod_data_confirm *)buf; switch((short unsigned int)(mm->module_id)) { case SUCCESS: faifa_printf(out_stream, "Status: Success\n"); break; case INV_MOD_ID: faifa_printf(out_stream, "Status: Invalid module ID\n"); return (len - avail); break; case BAD_HDR_CHKSUM: faifa_printf(out_stream, "Status: Bad header checksum\n"); return (len - avail); break; case INV_LEN: faifa_printf(out_stream, "Status: Invalid length\n"); return (len - avail); break; case UNEX_OFF: faifa_printf(out_stream, "Status: Unexpected offset\n"); return (len - avail); break; case INV_CHKSUM: faifa_printf(out_stream, "Status: Invalid checksum\n"); return (len - avail); break; default: break; } faifa_printf(out_stream, "Length: %d\n", (unsigned int)(mm->length)); faifa_printf(out_stream, "Offset: %08lx\n", (long unsigned int)(mm->offset)); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_read_mod_data_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct read_mod_data_request *mm = buf; faifa_printf(out_stream, "Module ID? "); fscanf(in_stream, "%2hx", (short unsigned int *)&(mm->module_id)); faifa_printf(out_stream, "Length? "); fscanf(in_stream, "%d", (int *)&(mm->length)); faifa_printf(out_stream, "Offset? "); fscanf(in_stream, "%d", (int *)&(mm->offset)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_read_mod_data_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct read_mod_data_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); faifa_printf(out_stream, "Module ID: 0x%02x\n", (short unsigned int)(mm->module_id)); faifa_printf(out_stream, "Length: %d\n", (short unsigned int)(mm->length)); faifa_printf(out_stream, "Offset: 0x%08x\n", (unsigned int)(mm->offset)); faifa_printf(out_stream, "Checksum: 0x%08x\n", (unsigned int)(mm->checksum)); faifa_printf(out_stream, "Data:\n"); dump_hex(mm->data + mm->offset, (unsigned int)(mm->length), " "); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_get_manuf_string_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_manuf_string_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->status) ? "Failure" : "Success"); faifa_printf(out_stream, "Length: %d (0x%02hx)\n", (short unsigned int)(mm->length), (short unsigned int)(mm->length)); faifa_printf(out_stream, "Manufacturer string: %s\n", (char *)(mm->data)); avail -= sizeof(*mm); return (len - avail); } static void dump_conf_block(struct block_header *hdr) { faifa_printf(out_stream, "Version: %08lx\n", (long unsigned int)(hdr->version)); faifa_printf(out_stream, "Image address in NVRAM: 0x%08lx\n", (long unsigned int)(hdr->img_rom_addr)); faifa_printf(out_stream, "Image address in SDRAM: 0x%08lx\n", (long unsigned int)(hdr->img_sdram_addr)); faifa_printf(out_stream, "Image length: %lu (0x%08lx)\n", (long unsigned int)(hdr->img_length), (long unsigned int)(hdr->img_length)); faifa_printf(out_stream, "Image checksum: %08lx\n", (long unsigned int)(hdr->img_checksum)); faifa_printf(out_stream, "Image SDRAM entry point: 0x%08lx\n", (long unsigned int)(hdr->entry_point)); faifa_printf(out_stream, "Address of next header: 0x%08lx\n", (long unsigned int)(hdr->next_header)); faifa_printf(out_stream, "Header checksum: 0x%08lx\n", (long unsigned int)(hdr->hdr_checksum)); } static void dump_sdram_block(struct sdram_config *config) { faifa_printf(out_stream, "Size : %lu (0x%08lx)\n", (long unsigned int)(config->size), (long unsigned int)(config->size)); faifa_printf(out_stream, "Configuration reg: 0x%08lx\n", (long unsigned int)(config->conf_reg)); faifa_printf(out_stream, "Timing reg0: 0x%08lx\n", (long unsigned int)(config->timing0)); faifa_printf(out_stream, "Timing reg1: 0x%08lx\n", (long unsigned int)(config->timing1)); faifa_printf(out_stream, "Control reg: 0x%08lx\n", (long unsigned int)(config->ctl_reg)); faifa_printf(out_stream, "Refresh reg: 0x%08lx\n", (long unsigned int)(config->ref_reg)); faifa_printf(out_stream, "MAC clock reg : %lu (0x%08lx)\n", (long unsigned int)(config->clk_reg_val), (long unsigned int)(config->clk_reg_val)); } static int hpav_dump_read_config_block_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct read_config_block_confirm *mm = buf; switch (mm->mstatus) { case 0x00: faifa_printf(out_stream, "Status: Success\n"); break; case 0x01: faifa_printf(out_stream, "Status: Failure\n"); goto out; break; case 0x10: faifa_printf(out_stream, "Status: No flash\n"); goto out; break; } faifa_printf(out_stream, "Config length: %d\n", (short unsigned int)(mm->config_length)); dump_conf_block(&(mm->hdr)); dump_sdram_block(&(mm->config)); out: avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_set_sdram_config_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; short unsigned int *status = (short unsigned int *)buf; switch (*status) { case SUCCESS: faifa_printf(out_stream, "Status: Success\n"); break; case SDR_INV_CHKSUM: faifa_printf(out_stream, "Status: Invalid checksum\n"); break; case SDR_BIST_FAILED: faifa_printf(out_stream, "Status: BIST failed\n"); break; default: break; } avail -= sizeof(*status); return (len - avail); } static int hpav_init_get_devices_attrs_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct get_devices_attrs_request *mm = buf; /* Generate a random number for the cookie */ srand(getpid()); mm->cookie = (long unsigned int)(random()); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_get_devices_attrs_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_devices_attrs_confirm *mm = buf; switch (mm->status) { case 0x00: faifa_printf(out_stream, "Status: Success\n"); break; case 0x01: faifa_printf(out_stream, "Status: Failure\n"); goto out; break; case 0x02: faifa_printf(out_stream, "Status: Not supported\n"); goto out; break; } faifa_printf(out_stream, "Cookie: %lu\n", (long unsigned int)(mm->cookie)); faifa_printf(out_stream, "Report type: %s\n", (short unsigned int)(mm->rtype) ? "XML" : "Binary"); faifa_printf(out_stream, "Size: %d\n", (unsigned int)(mm->size)); faifa_printf(out_stream, "Hardware: %s\n", mm->fmt.hardware); faifa_printf(out_stream, "Software: %s\n", mm->fmt.software); faifa_printf(out_stream, "Major: %lu\n", (long unsigned int)(mm->fmt.major)); faifa_printf(out_stream, "Minor: %lu\n", (long unsigned int)(mm->fmt.minor)); faifa_printf(out_stream, "Subversion: %lu\n", (long unsigned int)(mm->fmt.subversion)); faifa_printf(out_stream, "Build number: %lu\n", (long unsigned int)(mm->fmt.build_number)); faifa_printf(out_stream, "Build date: %s\n", mm->fmt.build_date); faifa_printf(out_stream, "Release type: %s\n", mm->fmt.release_type); out: avail -= sizeof(*mm); return (len - avail); } static int hpav_init_get_enet_phy_settings_request(void *buf, int len, void *UNUSED(user)) { int avail = len; struct get_enet_phy_settings_request *mm = buf; avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_get_enet_phy_settings_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_enet_phy_settings_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->status) ? "Failure" : "Success"); switch(mm->speed) { case ENET: faifa_printf(out_stream, "Speed: Ethernet (10Mbits)\n"); break; case FA_ENET: faifa_printf(out_stream, "Speed: Fast Ethernet (100Mbits)\n"); break; case GIG_ENET: faifa_printf(out_stream, "Speed : Gigabit Ethernet (1Gbits)\n"); break; } faifa_printf(out_stream, "Duplex: %s\n", (short unsigned int)(mm->duplex) ? "Full duplex" : "Half duplex"); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_get_tone_map_charac_request(void *buf, int len, void *UNUSED(user)) { int avail = len; short unsigned macaddr[6]; int i; struct get_tone_map_charac_request *mm = buf; faifa_printf(out_stream, "Address of peer node?\n"); fscanf(in_stream, "%2hx:%2hx:%2hx:%2hx:%2hx:%2hx", (short unsigned int *)&macaddr[0], (short unsigned int *)&macaddr[1], (short unsigned int *)&macaddr[2], (short unsigned int *)&macaddr[3], (short unsigned int *)&macaddr[4], (short unsigned int *)&macaddr[5]); for (i = 0; i < 6; i++) mm->macaddr[i] = macaddr[i]; faifa_printf(out_stream, "Tone map slot?\n0 -> slot 0\n1 -> slot 1 ...\n"); fscanf(in_stream, "%2hx", (short unsigned int *)&(mm->tmslot)); avail -= sizeof(*mm); return (len - avail); } char *get_carrier_modulation_str(short unsigned int modulation, struct modulation_stats *stats) { switch(modulation) { case NO: stats->no++; return "No"; break; case BPSK: stats->bpsk++; return "BPSK"; break; case QPSK: stats->qpsk++; return "QPSK"; break; case QAM_8: stats->qam8++; return "QAM-8"; break; case QAM_16: stats->qam16++; return "QAM-16"; break; case QAM_64: stats->qam64++; return "QAM-64"; break; case QAM_256: stats->qam256++; return "QAM-256"; break; case QAM_1024: stats->qam1024++; return "QAM-1024"; break; default: stats->unknown++; return "Unknown"; break; } } static void dump_modulation_stats(struct modulation_stats *stats) { unsigned sum = 0; sum = stats->no + stats->bpsk + stats->qpsk + stats->qam8 + stats->qam16 + stats->qam64 + stats->qam256 + stats->qam1024 + stats->unknown; faifa_printf(out_stream, "Number of carriers with NO modulation: %d (%f %%)\n", stats->no, (double)((stats->no * 100) / sum)); faifa_printf(out_stream, "Number of carriers with BPSK modulation: %d (%f %%)\n", stats->bpsk, (double)((stats->bpsk * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QPSK modulation: %d (%f %%)\n", stats->qpsk, (double)((stats->qpsk * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QAM-8 modulation: %d (%f %%)\n", stats->qam8, (double)((stats->qam8 * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QAM-16 modulation: %d (%f %%)\n", stats->qam16, (double)((stats->qam16 * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QAM-64 modulation: %d (%f %%)\n", stats->qam64, (double)((stats->qam64 * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QAM-256 modulation: %d (%f %%)\n", stats->qam256, (double)((stats->qam256 * 100) / sum)); faifa_printf(out_stream, "Number of carriers with QAM-1024 modulation: %d (%f %%)\n", stats->qam1024, (double)((stats->qam1024 * 100) / sum)); faifa_printf(out_stream, "Number of carriers with Unknown/unused modulation: %d (%f %%)\n", stats->unknown, (double)((stats->unknown * 100) / sum)); faifa_printf(out_stream, "Number of modulation: %d\n", sum); } static int hpav_dump_get_tone_map_charac_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; int i; struct get_tone_map_charac_confirm *mm = buf; struct modulation_stats stats; switch (mm->mstatus) { case 0x00: faifa_printf(out_stream, "Status: Success\n"); break; case 0x01: faifa_printf(out_stream, "Status: Unknown MAC address\n"); goto out; break; case 0x02: faifa_printf(out_stream, "Status: unknown ToneMap slot\n"); goto out; break; } faifa_printf(out_stream, "Tone map slot: %02d\n", (short unsigned int)(mm->tmslot)); faifa_printf(out_stream, "Number of tone map: %02d\n", (short unsigned int)(mm->num_tms)); faifa_printf(out_stream, "Tone map number of activer carriers: %d\n", (unsigned int)(mm->tm_num_act_carrier)); memset(&stats, 0, sizeof(stats)); for (i = 0; i < MAX_CARRIERS; i++) { faifa_printf(out_stream, "Modulation for carrier: %d : %s\n", i, get_carrier_modulation_str(mm->carriers[i].mod_carrier_lo, &stats)); faifa_printf(out_stream, "Modulation for carrier: %d : %s\n", i + 1, get_carrier_modulation_str(mm->carriers[i].mod_carrier_hi, &stats)); } faifa_printf(out_stream, "Modulation statistics\n"); dump_modulation_stats(&stats); out: avail -= sizeof(*mm); return (len - avail); } static int hpav_init_watchdog_report_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct get_watchdog_report_request *mm = buf; srand(getpid()); mm->session_id = (unsigned int)(random()); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_watchdog_report_indicate(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct get_watchdog_report_indicate *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); faifa_printf(out_stream, "Session ID: %d\n", (unsigned int)(mm->session_id)); faifa_printf(out_stream, "Number of parts: %d\n", (short unsigned int)(mm->num_parts)); faifa_printf(out_stream, "Current part: %d\n", (short unsigned int)(mm->cur_part)); faifa_printf(out_stream, "Data length: %d\n", (unsigned int)(mm->data_length)); faifa_printf(out_stream, "Data offset: 0x%02hx\n", (short unsigned int)(mm->data_offset)); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_link_stats_request(void *buf, int len, void *UNUSED(user)) { int avail = len; struct link_statistics_request *mm = buf; short unsigned int link_id; short unsigned int macaddr[6]; int i; int direction; faifa_printf(out_stream, "Direction ?\n0: TX\n1: RX\n2: TX and RX\n"); fscanf(in_stream, "%2d", &direction); if (direction >= 0 || direction <= 2) mm->direction = (short unsigned int)(direction); faifa_printf(out_stream, "Link ID ?\n"); fscanf(in_stream, "%2hx", &link_id); switch(link_id) { case HPAV_LID_CSMA_CAP_0: case HPAV_LID_CSMA_CAP_1: case HPAV_LID_CSMA_CAP_2: case HPAV_LID_CSMA_CAP_3: case HPAV_LID_CSMA_SUM: case HPAV_LID_CSMA_SUM_ANY: mm->link_id = link_id; break; default: mm->link_id = HPAV_LID_CSMA_SUM; faifa_printf(err_stream, "Invalid Link ID selected, defaulting to all CSMA stats\n"); break; } if (link_id != HPAV_LID_CSMA_SUM_ANY) { faifa_printf(out_stream, "Address of peer node?\n"); fscanf(in_stream, "%2hx:%2hx:%2hx:%2hx:%2hx:%2hx", (short unsigned int *)&macaddr[0], (short unsigned int *)&macaddr[1], (short unsigned int *)&macaddr[2], (short unsigned int *)&macaddr[3], (short unsigned int *)&macaddr[4], (short unsigned int *)&macaddr[5]); for (i = 0; i < 6; i++) mm->macaddr[i] = macaddr[i]; } avail -= sizeof(*mm); return (len - avail); } static void dump_tx_link_stats(struct tx_link_stats *tx) { faifa_printf(out_stream, "MPDU acked......................: %llu\n", (long long unsigned)(tx->mpdu_ack)); faifa_printf(out_stream, "MPDU collisions.................: %llu\n", (long long unsigned)(tx->mpdu_coll)); faifa_printf(out_stream, "MPDU failures...................: %llu\n", (long long unsigned)(tx->mpdu_fail)); faifa_printf(out_stream, "PB transmitted successfully.....: %llu\n", (long long unsigned)(tx->pb_passed)); faifa_printf(out_stream, "PB transmitted unsuccessfully...: %llu\n", (long long unsigned)(tx->pb_failed)); } static void dump_rx_link_stats(struct rx_link_stats *rx) { int i; faifa_printf(out_stream, "MPDU acked......................: %llu\n", (long long unsigned)(rx->mpdu_ack)); faifa_printf(out_stream, "MPDU failures...................: %llu\n", (long long unsigned)(rx->mpdu_fail)); faifa_printf(out_stream, "PB received successfully........: %llu\n", (long long unsigned)(rx->pb_passed)); faifa_printf(out_stream, "PB received unsuccessfully......: %llu\n", (long long unsigned)(rx->pb_failed)); faifa_printf(out_stream, "Turbo Bit Errors passed.........: %llu\n", (long long unsigned)(rx->tbe_passed)); faifa_printf(out_stream, "Turbo Bit Errors failed.........: %llu\n", (long long unsigned)(rx->tbe_failed)); for (i = 0; i < rx->num_rx_intervals; i++) { faifa_printf(out_stream, "-- Rx interval %d --\n", i); faifa_printf(out_stream, "Rx PHY rate.....................: %02d\n", (short unsigned int)(rx->rx_interval_stats[i].phyrate)); faifa_printf(out_stream, "PB received successfully........: %llu\n", (long long unsigned)(rx->rx_interval_stats[i].pb_passed)); faifa_printf(out_stream, "PB received failed..............: %llu\n", (long long unsigned)(rx->rx_interval_stats[i].pb_failed)); faifa_printf(out_stream, "TBE errors over successfully....: %llu\n", (long long unsigned)(rx->rx_interval_stats[i].tbe_passed)); faifa_printf(out_stream, "TBE errors over failed..........: %llu\n", (long long unsigned)(rx->rx_interval_stats[i].tbe_failed)); } } static int hpav_dump_link_stats_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct link_statistics_confirm *mm = buf; switch(mm->mstatus) { case HPAV_SUC: faifa_printf(out_stream, "Status: Success\n"); break; case HPAV_INV_CTL: faifa_printf(out_stream, "Status: Invalid control\n"); goto out; break; case HPAV_INV_DIR: faifa_printf(out_stream, "Status: Invalid direction\n"); goto out; break; case HPAV_INV_LID: faifa_printf(out_stream, "Status: Invalid Link ID\n"); goto out; break; case HPAV_INV_MAC: faifa_printf(out_stream, "Status: Invalid MAC address\n"); goto out; break; } faifa_printf(out_stream, "Link ID: %02hx\n", (short unsigned int)(mm->link_id)); faifa_printf(out_stream, "TEI: %02hx\n", (short unsigned int)(mm->tei)); switch (mm->direction) { case HPAV_SD_TX: faifa_printf(out_stream, "Direction: Tx\n"); dump_tx_link_stats(&(mm->tx)); break; case HPAV_SD_RX: faifa_printf(out_stream, "Direction: Rx\n"); dump_rx_link_stats(&(mm->rx)); break; case HPAV_SD_BOTH: faifa_printf(out_stream, "Direction: Tx\n"); dump_tx_link_stats(&(mm->both.tx)); faifa_printf(out_stream, "Direction: Rx\n"); dump_rx_link_stats(&(mm->both.rx)); break; default: break; } out: avail -= sizeof(*mm); return (len - avail); } static char *get_sniffer_control_str(int control) { static char *control_unknown = "unknown"; static char *controls[] = { [HPAV_SC_DISABLE] = "disable", [HPAV_SC_ENABLE] = "enable", [HPAV_SC_NO_CHANGE] = "no change", }; if ((HPAV_SC_DISABLE <= control) && (control <= HPAV_SC_NO_CHANGE)) { return controls[control]; } return control_unknown; } static int hpav_init_sniffer_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct sniffer_request *mm = buf; int control; faifa_printf(out_stream, "Sniffer mode?\n"); for (control = HPAV_SC_DISABLE; control <= HPAV_SC_NO_CHANGE; control++) { faifa_printf(out_stream, "%d: %s\n", control, get_sniffer_control_str(control)); } fscanf(in_stream, "%d", &control); switch(control) { case HPAV_SC_DISABLE: case HPAV_SC_ENABLE: case HPAV_SC_NO_CHANGE: mm->control = control; break; default: mm->control = HPAV_SC_NO_CHANGE; faifa_printf(err_stream, "Invalid sniffer mode selected, no change\n"); break; } avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_sniffer_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct sniffer_request *mm = buf; faifa_printf(out_stream, "Sniffer mode : 0x%02hx (%s)\n", mm->control, get_sniffer_control_str(mm->control)); avail -= sizeof(*mm); return (len - avail); } static char *get_sniffer_state_str(int state) { static char *state_unknown = "unknown"; static char *states[] = { [HPAV_ST_DISABLED] = "disabled", [HPAV_ST_ENABLED] = "enabled", }; if ((HPAV_ST_DISABLED <= state) && (state <= HPAV_ST_ENABLED)) { return states[state]; } return state_unknown; } static int hpav_dump_sniffer_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct sniffer_confirm *mm = buf; faifa_printf(out_stream, "Status: 0x%02hx\n", mm->mstatus); faifa_printf(out_stream, "Sniffer State: 0x%02hx (%s)\n", mm->state, get_sniffer_state_str(mm->state)); avail -= sizeof(*mm); faifa_printf(out_stream, "Destination MAC Address: "); avail -= dump_hex(mm->da, sizeof(mm->da), ":"); faifa_printf(out_stream, "\n"); avail -= sizeof(*mm); return (len - avail); } static void dump_hpav_frame_ctl(struct hpav_fc *fc) { u_int8_t rg_len; faifa_printf(out_stream, "Delimiter type: %1hx\n", (short unsigned int)(fc->del_type)); faifa_printf(out_stream, "Access: %s\n", fc->access ? "Yes" : "No"); faifa_printf(out_stream, "SNID: %1hx\n", (short unsigned int)(fc->snid)); faifa_printf(out_stream, "STEI: %02hx\n", (short unsigned int)(fc->stei)); faifa_printf(out_stream, "DTEI: %02hx\n", (short unsigned int)(fc->dtei)); faifa_printf(out_stream, "Link ID: %02hx\n", (short unsigned int)(fc->lid)); faifa_printf(out_stream, "Contention free session: %s\n", fc->cfs ? "Yes" : "No"); faifa_printf(out_stream, "Beacon detect flag: %s\n", fc->bdf ? "Yes" : "No"); faifa_printf(out_stream, "HPAV version 1.0: %s\n", fc->hp10df ? "Yes" : "No"); faifa_printf(out_stream, "HPAV version 1.1: %s\n", fc->hp11df ? "Yes" : "No"); faifa_printf(out_stream, "EKS: %1hx\n", (short unsigned int)(fc->eks)); faifa_printf(out_stream, "Pending PHY blocks: %02hx\n", (short unsigned int)(fc->ppb)); faifa_printf(out_stream, "Bit loading estimate: %02hx\n", (short unsigned int)(fc->ble)); faifa_printf(out_stream, "PHY block size: %s\n", fc->pbsz ? "Yes" : "No"); faifa_printf(out_stream, "Number of symbols: %1hx\n", (short unsigned int)(fc->num_sym)); faifa_printf(out_stream, "Tonemap index: %1hx\n", (short unsigned int)(fc->tmi_av)); faifa_printf(out_stream, "HPAV frame length: %3hx\n", (short unsigned int)(fc->fl_av)); faifa_printf(out_stream, "MPDU count: %1hx\n", (short unsigned int)(fc->mpdu_cnt)); faifa_printf(out_stream, "Burst count: %1hx\n", (short unsigned int)(fc->burst_cnt)); faifa_printf(out_stream, "Convergence layer SAP type: %1hx\n", (short unsigned int)(fc->clst)); rg_len = (fc->rg_len_hi << 5) | fc->rg_len_lo; faifa_printf(out_stream, "Reverse Grant length: %2hx\n", (short unsigned int)(rg_len)); faifa_printf(out_stream, "Management MAC Frame Stream Command: %1hx\n", (short unsigned int)(fc->mfs_cmd_mgmt)); faifa_printf(out_stream, "Data MAC Frame Stream Command: %1hx\n", (short unsigned int)(fc->mfs_cmd_data)); faifa_printf(out_stream, "Request SACK Retransmission: %s\n", fc->rsr ? "Yes" : "No"); faifa_printf(out_stream, "Multicast: %s\n", fc->mcf ? "Yes" : "No"); faifa_printf(out_stream, "Different CP PHY Clock: %s\n", fc->mcf ? "Yes" : "No"); faifa_printf(out_stream, "Multinetwork Broadcast: %s\n", fc->mnbf ? "Yes" : "No"); faifa_printf(out_stream, "Frame control check sequence: %2hx%2hx%2hx\n", (unsigned int)(fc->fccs_av[0]), (unsigned int)(fc->fccs_av[1]), (unsigned int)(fc->fccs_av[2])); } static void dump_hpav_beacon(struct hpav_bcn *bcn) { faifa_printf(out_stream, "Delimiter type: %1hx\n", bcn->del_type); faifa_printf(out_stream, "Access: %s\n", bcn->access ? "Yes" : "No"); faifa_printf(out_stream, "SNID: %1hx\n", bcn->snid); faifa_printf(out_stream, "Beacon timestamp: %lu (0x%08lx)\n", (long unsigned int)(bcn->bts), (long unsigned int)(bcn->bts)); faifa_printf(out_stream, "Beacon transmission offset 0: %d (0x%04hx)\n", bcn->bto_0, (unsigned int)(bcn->bto_0)); faifa_printf(out_stream, "Beacon transmission offset 1: %d (0x%04hx)\n", bcn->bto_1, (unsigned int)(bcn->bto_1)); faifa_printf(out_stream, "Beacon transmission offset 2: %d (0x%04hx)\n", bcn->bto_2, (unsigned int)(bcn->bto_2)); faifa_printf(out_stream, "Beacon transmission offset 3: %d (0x%04hx)\n", bcn->bto_3, (unsigned int)(bcn->bto_3)); faifa_printf(out_stream, "Frame control check sequence: %2hx%2hx%2hx\n", (unsigned int)(bcn->fccs_av[0]), (unsigned int)(bcn->fccs_av[1]), (unsigned int)(bcn->fccs_av[2])); } static int hpav_dump_sniffer_indicate(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct sniffer_indicate *mm = buf; faifa_printf(out_stream, "Type: %s\n", (short unsigned int)(mm->type) ? "Unknown" : "Regular"); faifa_printf(out_stream, "Direction: %s\n", (short unsigned int)(mm->direction) ? "Rx" : "Tx"); faifa_printf(out_stream, "System time: %llu\n", (long long unsigned int)(mm->systime)); faifa_printf(out_stream, "Beacon time: %lu\n", (long unsigned)(mm->beacontime)); dump_hpav_frame_ctl(&(mm->fc)); dump_hpav_beacon(&(mm->bcn)); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_check_points_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct check_points_request *mm = buf; srand(getpid()); mm->session_id = (unsigned int)(random()); /* Do not clear the check points yet */ mm->clr_flag = 0x00; avail -= sizeof(*mm); return (len - avail); } char *get_sta_role_str(u_int8_t sta_role) { switch (sta_role) { case HPAV_SR_STA: return "Station"; break; case HPAV_SR_PROXY: return "Proxy coordinator"; break; case HPAV_SR_CCO: return "Network coordinator"; break; default: return NULL; } return NULL; } static int hpav_dump_network_info_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct network_info_confirm *mm = buf; int i; faifa_printf(out_stream, "Network ID (NID): "); dump_hex(&(mm->nid), sizeof(mm->nid), " "); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "Short Network ID (SNID): 0x%02hx\n", mm->snid); faifa_printf(out_stream, "STA TEI: 0x%02hx\n", mm->tei); faifa_printf(out_stream, "STA Role: %s\n", get_sta_role_str(mm->sta_role)); faifa_printf(out_stream, "CCo MAC: \n"); faifa_printf(out_stream, "\t"); dump_hex(&(mm->cco_macaddr), sizeof(mm->cco_macaddr), ":"); faifa_printf(out_stream, "\nCCo TEI: 0x%02hx\n", mm->cco_tei); faifa_printf(out_stream, "Stations: %d\n", mm->num_stas); avail -= sizeof(*mm); if (mm->num_stas > 0) { faifa_printf(out_stream, "Station MAC TEI Bridge MAC TX RX \n"); faifa_printf(out_stream, "----------------- ---- ----------------- ---- ----\n"); for (i = 0; i < mm->num_stas; i++) { dump_hex(mm->stas[i].sta_macaddr, sizeof(mm->stas[i].sta_macaddr), ":"); faifa_printf(out_stream, " 0x%02hx ", mm->stas[i].sta_tei); dump_hex(mm->stas[i].bridge_macaddr, sizeof(mm->stas[i].bridge_macaddr), ":"); faifa_printf(out_stream, " 0x%02hx", mm->stas[i].avg_phy_tx_rate); faifa_printf(out_stream, " 0x%02hx\n", mm->stas[i].avg_phy_rx_rate); } } return (len - avail); } static int hpav_dump_check_points_indicate(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct check_points_indicate *mm = buf; faifa_printf(out_stream, "Status: %s\n", mm->mstatus ? "Failure" : "Success"); faifa_printf(out_stream, "Major: %s\n", mm->major ? "< 1.4" : "> 1.4"); faifa_printf(out_stream, "Checkpoint buffer locked: %s\n", mm->buf_locked ? "Yes" : "No"); faifa_printf(out_stream, "Auto-lock on reset supported: %s\n", mm->auto_lock ? "Yes" : "No"); faifa_printf(out_stream, "Unsollicited update supported: %s\n", mm->unsoc_upd ? "Yes" : "No"); faifa_printf(out_stream, "Unsollicited: %s\n", mm->unsoc ? "Yes" : "No"); faifa_printf(out_stream, "Session: %04hx\n", (unsigned int)(mm->session_id)); faifa_printf(out_stream, "Length: %lu (0x%08lx)\n", (long unsigned)(mm->length), (long unsigned)(mm->length)); faifa_printf(out_stream, "Offset: 0x%08lx\n", (long unsigned)(mm->offset)); faifa_printf(out_stream, "Next index: 0x%08lx\n", (long unsigned)(mm->index)); faifa_printf(out_stream, "Number of parts: %d\n", (short unsigned int)(mm->num_parts)); faifa_printf(out_stream, "Current part: %d\n", (short unsigned int)(mm->cur_part)); faifa_printf(out_stream, "Data length: %d (0x%04hx)\n", (unsigned int)(mm->data_length), (unsigned int)(mm->data_length)); faifa_printf(out_stream, "Data offset: 0x%04hx\n", (unsigned int)(mm->data_offset)); /* FIXME: we should probably move the offset */ //dump_hex(mm->data + mm->data_offset, (unsigned int)(mm->data_length), " "); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_loopback_request(void *buf, int len, void *UNUSED(buffer)) { int avail = len; struct loopback_request *mm = buf; int duration; u_int8_t eth_test_frame[512]; faifa_printf(out_stream, "Duration ?\n"); fscanf(in_stream, "%2d", &duration); if (duration >= 0 || duration <= 60) mm->duration = (short unsigned int)(duration); /* FIXME: building a static test frame */ ether_init_header(eth_test_frame, 512, broadcast_macaddr, broadcast_macaddr, ETHERTYPE_HOMEPLUG_AV); memcpy(mm->data, eth_test_frame, sizeof(eth_test_frame)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_loopback_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct loopback_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); faifa_printf(out_stream, "Duration: %d\n", (short unsigned int)(mm->duration)); faifa_printf(out_stream, "Length: %d\n", (unsigned int)(mm->length)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_loopback_status_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct loopback_status_confirm *mm = buf; faifa_printf(out_stream, "Status: %s\n", (short unsigned int)(mm->mstatus) ? "Failure" : "Success"); faifa_printf(out_stream, "State: %s\n", (short unsigned int)(mm->state) ? "Looping frame" : "Done"); avail -= sizeof(*mm); return (len - avail); } static int hpav_init_set_enc_key_request(void *buf, int len, void *UNUSED(user)) { int avail = len; struct set_encryption_key_request *mm = buf; int i, local; u_int8_t key[16], dak[16]; char nek[16], dek[16]; short unsigned int macaddr[6]; faifa_printf(out_stream, "Local or distant setting ?\n"); faifa_printf(out_stream, "0: distant\n1: local\n"); fscanf(in_stream, "%d", &local); /* Old versions should use 0x03 */ mm->peks = 0x01; mm->peks_payload = 0x0f; faifa_printf(out_stream, "AES NMK key ?"); fscanf(in_stream, "%s", nek); /* Generate the key from the NEK and and NMK Salt */ gen_passphrase(nek, key, nmk_salt); memcpy(mm->nmk, key, AES_KEY_SIZE); /* If we are setting a remote device ask for more options */ if (!local) { faifa_printf(out_stream, "Device DEK ?\n"); fscanf(in_stream, "%s", dek); /* Generate the key from the DEK and DAK salt */ gen_passphrase(dek, dak, dak_salt); memcpy(mm->nmk_payload, dak, AES_KEY_SIZE); mm->peks_payload = 0x00; /* Broadcast the key */ for (i = 0; i < 6; i++) mm->rdra[i] = 0xFF; } else { /* Ask for the station MAC address */ faifa_printf(out_stream, "Destination MAC address ?"); fscanf(in_stream, "%2hx:%2hx:%2hx:%2hx:%2hx:%2hx", (short unsigned int *)&macaddr[0], (short unsigned int *)&macaddr[1], (short unsigned int *)&macaddr[2], (short unsigned int *)&macaddr[3], (short unsigned int *)&macaddr[4], (short unsigned int *)&macaddr[5]); /* Set the desination address */ for (i = 0; i < 6; i++) mm->rdra[i] = macaddr[i]; } avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_set_enc_key_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; short unsigned int *status = (short unsigned int *)buf; switch(*status) { case KEY_SUCCESS: faifa_printf(out_stream, "Status: Success\n"); break; case KEY_INV_EKS: faifa_printf(out_stream, "Status: Invalid EKS\n"); break; case KEY_INV_PKS: faifa_printf(out_stream, "Status: Invalid PKS\n"); break; case KEY_UKN: faifa_printf(out_stream, "Unknown result: %02hx\n", *status); break; } avail -= sizeof(*status); return (len - avail); } static char *get_peks_str(u_int8_t peks) { switch (peks) { case DST_STA_DAK: return "Destination Station DAK"; break; case NMK_KNOWN_STA: return "NMK known to station"; break; case ID_TEKS: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: return "Identifies TEKs"; break; case NO_KEY: default: return "No key"; break; } return NULL; } static char *get_avln_status_str(u_int8_t avln_status) { switch (avln_status) { case UN_ASSOC_LVL_0: return "Unassociated and Level-0 CCo capable"; break; case UN_ASSOC_LVL_1: return "Unassociated and Level-1 CCo capable"; break; case UN_ASSOC_LVL_2: return "Unassociated and Level-2 CCo capable"; break; case UN_ASSOC_LVL_3: return "Unassociated and Level-3 CCo capable"; break; case UN_ASSOC_NPCO: return "Associated with AV LAN but not PCo capable"; break; case UN_ASSOC_PCO: return "Associated with AV LAN and PCo capable"; break; case CCO_AVLN: return "CCo of an AV LAN"; break; default: return NULL; break; } return NULL; } static char *get_pid_str(u_int8_t pid) { switch (pid) { case AUTH_REQ_NEW: return "Authentication request by new STA"; break; case PROV_STA_NEW: return "Provision authenticated STA with new NEK by CCo"; break; case PROV_STA_DAK: return "Provision STA with NMK using DAK"; break; case PROV_STA_UKE: return "Provision STA with NMK using UKE"; break; case HLE_PROTO: return "HLE protocol"; break; default: return NULL; break; } return NULL; } static int hpav_dump_enc_payload_indicate(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_enc_payload_indicate *mm = buf; unsigned proto = 0; if (mm->pid == HLE_PROTO) proto = 1; faifa_printf(out_stream, "PEKS: %s\n", get_peks_str(mm->peks)); faifa_printf(out_stream, "HPAV Lan status: %s\n", get_avln_status_str(mm->avln_status)); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); faifa_printf(out_stream, "PMN: %02hx\n", (short unsigned int)(mm->pmn)); faifa_printf(out_stream, "%s: ", proto ? "UUID" : "AES IV"); dump_hex(mm->aes_iv_uuid, AES_KEY_SIZE, " "); faifa_printf(out_stream, "\n"); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_enc_payload_response(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_enc_payload_response *mm = buf; faifa_printf(out_stream, "Result: %s\n", (short unsigned int)(mm->result) ? "Failure/Abort" : "Success"); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); avail -= sizeof(*mm); return (len - avail); } static char *get_key_type_str(u_int8_t key_type) { switch (key_type) { case DAK_AES_128: return "DAK (AES-128)"; break; case NMK_AES_128: return "NMK (AES-128)"; break; case NEK_AES_128: return "NEK (AES-128)"; break; case TEK_AES_128: return "TEK (AES-128)"; break; case HASH_KEY: return "Hash key"; break; case NONCE_ONLY: return "Nonce only"; break; default: return NULL; } return NULL; } static int hpav_dump_cm_set_key_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_set_key_request *mm = buf; faifa_printf(out_stream, "Key type: %s\n", get_key_type_str(mm->key_type)); faifa_printf(out_stream, "My nonce: %08lx\n", (long unsigned int)(mm->my_nonce)); faifa_printf(out_stream, "Your nonce: %08lx\n", (long unsigned int)(mm->your_nonce)); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); faifa_printf(out_stream, "CCo cap: %02hx\n", (short unsigned int)(mm->cco_cap)); faifa_printf(out_stream, "NID "); dump_hex(mm->nid, sizeof(mm->nid), "");faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "New EKS: %02hx\n", (short unsigned int)(mm->new_eks)); faifa_printf(out_stream, "New Key: "); dump_hex(mm->new_key, AES_KEY_SIZE, ""); faifa_printf(out_stream, "\n"); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_cm_set_key_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_set_key_confirm *mm = buf; faifa_printf(out_stream, "Result: %s\n", mm->result ? "Failure" : "Success"); faifa_printf(out_stream, "My nonce: %08lx\n", (long unsigned int)(mm->my_nonce)); faifa_printf(out_stream, "Your nonce: %08lx\n", (long unsigned int)(mm->your_nonce)); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); faifa_printf(out_stream, "CCo cap: %02hx\n", (short unsigned int)(mm->cco_cap)); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_cm_get_key_request(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_get_key_request *mm = buf; faifa_printf(out_stream, "Request type: %s\n", mm->req_type ? "Relayed" : "Direct"); faifa_printf(out_stream, "Key type: %s\n", get_key_type_str(mm->req_key_type)); faifa_printf(out_stream, "NID "); dump_hex(mm->nid, sizeof(mm->nid), "");faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "My nonce: %08lx\n", (long unsigned int)(mm->my_nonce)); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); faifa_printf(out_stream, "PMN: %02hx\n", (short unsigned int)(mm->pmn)); if (mm->req_key_type == HASH_KEY) faifa_printf(out_stream, "Hash key: ");dump_hex(mm->hash_key, len, "");faifa_printf(out_stream, "\n"); avail -= sizeof(*mm); return (len - avail); } static char *get_key_result_str(u_int8_t result) { switch (result) { case 0x00: return "Key granted"; break; case 0x01: return "Key refused"; break; case 0x02: return "Unsupported key/method"; break; default: return NULL; break; } return NULL; } static int hpav_dump_cm_get_key_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_get_key_confirm *mm = buf; faifa_printf(out_stream, "Result :%s\n", get_key_result_str(mm->result)); faifa_printf(out_stream, "Key type: %s\n", get_key_type_str(mm->req_key_type)); faifa_printf(out_stream, "My nonce: %08lx\n", (long unsigned int)(mm->my_nonce)); faifa_printf(out_stream, "Your nonce: %08lx\n", (long unsigned int)(mm->your_nonce)); faifa_printf(out_stream, "NID "); dump_hex(mm->nid, sizeof(mm->nid), "");faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "EKS: %02hx\n", (short unsigned int)(mm->eks)); faifa_printf(out_stream, "PID: %s\n", get_pid_str(mm->pid)); faifa_printf(out_stream, "PRN: %02hx\n", (short unsigned int)(mm->prn)); faifa_printf(out_stream, "PMN: %02hx\n", (short unsigned int)(mm->pmn)); faifa_printf(out_stream, "Hash key: ");dump_hex(mm->key, len, "");faifa_printf(out_stream, "\n"); avail -= sizeof(*mm); return (len - avail); } static int hpav_dump_cm_bridge_infos_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_brigde_infos_confirm *mm = buf; faifa_printf(out_stream, "Bridging: %s\n", mm->bsf ? "Yes" : "No"); if (mm->bsf) { int i; faifa_printf(out_stream, "Bridge TEI: %02hx\n", (short unsigned int)(mm->bridge_infos.btei)); faifa_printf(out_stream, "Number of stations: %d\n", mm->bridge_infos.nbda); for (i = 0; i < mm->bridge_infos.nbda; i++) { faifa_printf(out_stream, "Bridged station %d", i); dump_hex(mm->bridge_infos.bri_addr[i], 6, ":");faifa_printf(out_stream, "\n"); } } avail -= sizeof(*mm); return (len - avail); } static char *get_net_access_str(u_int8_t access) { switch (access) { case 0x00: return "In-Home network"; break; case 0x01: return "Access network"; break; default: return "Unknown"; break; } return NULL; } static void dump_cm_net_info(struct cm_net_info *net_info) { faifa_printf(out_stream, "NID: "); dump_hex(net_info->nid, sizeof(net_info->nid), " "); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "TEI: 0x%02hX (%d)\n", net_info->tei, net_info->tei); faifa_printf(out_stream, "STA Role: 0x%02hX (%s)\n", net_info->sta_role, get_sta_role_str(net_info->sta_role)); faifa_printf(out_stream, "MAC address: "); dump_hex(net_info->macaddr, 6, ":"); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "Access: 0x%02hX (%s)\n", net_info->access, get_net_access_str(net_info->access)); faifa_printf(out_stream, "Number of neighbors: %d\n", net_info->num_cord); } static int hpav_dump_cm_get_network_infos_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_get_network_infos_confirm *mm = buf; int i; avail -= sizeof(*mm); for (i = 0; i < mm->net.count; i++) { dump_cm_net_info(&(mm->net.infos[i])); avail -= sizeof(mm->net.infos[i]); } return (len - avail); } static void dump_cm_sta_info(struct cm_sta_info *sta_info) { faifa_printf(out_stream, "MAC address: "); dump_hex(sta_info->macaddr, 6, ":"); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "Average data rate from STA to DA: %d\n", sta_info->avg_phy_dr_tx); faifa_printf(out_stream, "Average data rate from DA to STA: %d\n", sta_info->avg_phy_dr_rx); } static int hpav_dump_cm_get_network_stats_confirm(void *buf, int len, struct ether_header *UNUSED(hdr)) { int avail = len; struct cm_get_network_stats_confirm *mm = buf; int i; avail -= sizeof(*mm); for (i = 0; i < mm->sta.count; i++) { dump_cm_sta_info(&(mm->sta.infos[i])); avail -= sizeof(mm->sta.infos[i]); } return (len - avail); } /** * frame_ops - array of the available frame operations */ struct hpav_frame_ops hpav_frame_ops[] = { { .mmtype = 0x0014, .desc = "Central Coordination Discover List Request", .init_frame = init_empty_frame, }, { .mmtype = 0x0015, .desc = "Central Coordination Discover List Confirm", .dump_frame = hpav_dump_cc_discover_list_confirm, }, { .mmtype = 0x6004, .desc = "Encrypted Payload Indicate", .dump_frame = hpav_dump_enc_payload_indicate, }, { .mmtype = 0x6005, .desc = "Encrypted Payload Response", .dump_frame = hpav_dump_enc_payload_response, }, { .mmtype = 0x6008, .desc = "Set Key Request", .dump_frame = hpav_dump_cm_set_key_request, }, { .mmtype = 0x6009, .desc = "Set Key Confirm", .dump_frame = hpav_dump_cm_set_key_confirm, }, { .mmtype = 0x600C, .desc = "Get Key Request", .dump_frame = hpav_dump_cm_get_key_request, }, { .mmtype = 0x600D, .desc = "Get Key Confirm", .dump_frame = hpav_dump_cm_get_key_confirm, }, { .mmtype = 0x6020, .desc = "Get Bridge Infos Request", .init_frame = init_empty_frame, }, { .mmtype = 0x6021, .desc = "Get Bridge Infos Confirm", .dump_frame = hpav_dump_cm_bridge_infos_confirm, }, { .mmtype = 0x6038, .desc = "Get Network Infos Request", .init_frame = init_empty_frame, }, { .mmtype = 0x6039, .desc = "Get Network Infos Confirm", .dump_frame = hpav_dump_cm_get_network_infos_confirm, }, { .mmtype = 0x6048, .desc = "Get Network Stats Request", .init_frame = init_empty_frame, }, { .mmtype = 0x6049, .desc = "Get Network Stats Confirm", .dump_frame = hpav_dump_cm_get_network_stats_confirm, }, { .mmtype = 0xA000, .desc = "Get Device/SW Version Request", .init_frame = init_empty_frame, }, { .mmtype = 0xA001, .desc = "Get Device/SW Version Confirm", .dump_frame = hpav_dump_get_device_sw_version_confirm, }, { .mmtype = 0xA004, .desc = "Write MAC Memory Request", .init_frame = hpav_init_write_mac_memory_request, .dump_frame = hpav_dump_write_mac_memory_request, }, { .mmtype = 0xA005, .desc = "Write MAC Memory Confirm", .dump_frame = hpav_dump_write_mac_memory_confirm, }, { .mmtype = 0xA008, .desc = "Read MAC Memory Request", .init_frame = hpav_init_read_mac_memory_request, .dump_frame = hpav_dump_read_mac_memory_request, }, { .mmtype = 0xA009, .desc = "Read MAC Memory Confirm", .dump_frame = hpav_dump_read_mac_memory_confirm, }, { .mmtype = 0xA00C, .desc = "Start MAC Request", .init_frame = hpav_init_start_mac_request, .dump_frame = hpav_dump_start_mac_request, }, { .mmtype = 0xA00D, .desc = "Start MAC Confirm", .dump_frame = hpav_dump_start_mac_confirm, }, { .mmtype = 0xA010, .desc = "Get NVM parameters Request", }, { .mmtype = 0xA011, .desc = "Get NVM parameters Confirm", .dump_frame = hpav_dump_nvram_params_confirm, }, { .mmtype = 0xA01C, .desc = "Reset Device Request", .init_frame = init_empty_frame, }, { .mmtype = 0xA01D, .desc = "Reset Device Confirm", .dump_frame = hpav_dump_reset_device_confirm, }, { .mmtype = 0xA020, .desc = "Write Module Data Request", .init_frame = hpav_init_write_data_request, }, { .mmtype = 0xA021, .desc = "Write Module Data Confirm", .dump_frame = hpav_dump_write_mod_data_confirm, }, { .mmtype = 0xA022, .desc = "Write Module Data Indicate", }, { .mmtype = 0xA024, .desc = "Read Module Data Request", .init_frame = hpav_init_read_mod_data_request, }, { .mmtype = 0xA025, .desc = "Read Module Data Confirm", .dump_frame = hpav_dump_read_mod_data_confirm, }, { .mmtype = 0xA028, .desc = "Write Module Data to NVM Request", }, { .mmtype = 0xA029, .desc = "Write Module Data to NVM Confirm", .dump_frame = hpav_dump_start_mac_confirm, }, { .mmtype = 0xA02C, .desc = "Get Watchdog Report Request", .init_frame = hpav_init_watchdog_report_request, }, { .mmtype = 0xA02E, .desc = "Get Watchdog Report Indicate", .dump_frame = hpav_dump_watchdog_report_indicate, }, { .mmtype = 0xA030, .desc = "Get Link Statistics Request", .init_frame = hpav_init_link_stats_request, }, { .mmtype = 0xA031, .desc = "Get Link Statistics Confirm", .dump_frame = hpav_dump_link_stats_confirm, }, { .mmtype = 0xA034, .desc = "Sniffer Mode Request", .init_frame = hpav_init_sniffer_request, .dump_frame = hpav_dump_sniffer_request, }, { .mmtype = 0xA035, .desc = "Sniffer Mode Confirm", .dump_frame = hpav_dump_sniffer_confirm, }, { .mmtype = 0xA036, .desc = "Sniffer Mode Indicate", .dump_frame = hpav_dump_sniffer_indicate, }, { .mmtype = 0xA038, .desc = "Network Info Request (Vendor-Specific)", .init_frame = init_empty_frame, }, { .mmtype = 0xA039, .desc = "Network Info Confirm (Vendor-Specific)", .dump_frame = hpav_dump_network_info_confirm, }, { .mmtype = 0xA040, .desc = "Check Points Request", .init_frame = hpav_init_check_points_request, }, { .mmtype = 0xA042, .desc = "Check Points Indicate", .dump_frame = hpav_dump_check_points_indicate, }, { .mmtype = 0xA048, .desc = "Loopback Request", .init_frame = hpav_dump_loopback_request, }, { .mmtype = 0xA049, .desc = "Loopback Confirm", .dump_frame = hpav_dump_loopback_confirm, }, { .mmtype = 0xA04C, .desc = "Loopback Status Request", .init_frame = init_empty_frame, }, { .mmtype = 0xA04D, .desc = "Loopback Status Confirm", .dump_frame = hpav_dump_loopback_status_confirm, }, { .mmtype = 0xA050, .desc = "Set Encryption Key Request", .init_frame = hpav_init_set_enc_key_request, }, { .mmtype = 0xA051, .desc = "Set Encryption Key Confirm", .dump_frame = hpav_dump_set_enc_key_confirm, }, { .mmtype = 0xA054, .desc = "Get Manufacturing String Request", .init_frame = init_empty_frame, }, { .mmtype = 0xA055, .desc = "Get Manufacturing String Confirm", .dump_frame = hpav_dump_get_manuf_string_confirm, }, { .mmtype = 0xA058, .desc = "Read Configuration Block Request", .init_frame = init_empty_frame, }, { .mmtype = 0xA059, .desc = "Read Configuration Block Confirm", .dump_frame = hpav_dump_read_config_block_confirm, }, { .mmtype = 0xA05C, .desc = "Set SDRAM Configuration Request", }, { .mmtype = 0xA05D, .desc = "Set SDRAM Configuration Confirm", .dump_frame = hpav_dump_set_sdram_config_confirm, }, { .mmtype = 0xA062, .desc = "Embedded Host Action Required Indicate", }, { .mmtype = 0xA063, .desc = "Embedded Host Action Required Response", }, { .mmtype = 0xA068, .desc = "Get Device Attributes Request", .init_frame = hpav_init_get_devices_attrs_request, }, { .mmtype = 0xA069, .desc = "Get Device Attributes Confirm", .dump_frame = hpav_dump_get_devices_attrs_confirm, }, { .mmtype = 0xA06C, .desc = "Get Ethernet PHY Settings Request", .init_frame = hpav_init_get_enet_phy_settings_request, }, { .mmtype = 0xA06D, .desc = "Get Ethernet PHY Settings Confirm", .dump_frame = hpav_dump_get_enet_phy_settings_confirm, }, { .mmtype = 0xA070, .desc = "Get Tone Map Caracteristics Request", .init_frame = hpav_init_get_tone_map_charac_request, }, { .mmtype = 0xA071, .desc = "Get Tone Map Characteristics Confirm", .dump_frame = hpav_dump_get_tone_map_charac_confirm, } }; /* HomePlug 1.0 frame operations */ static int hp10_init_channel_estimation_request(void *buf, int len, void *UNUSED(user)) { int avail = len; struct hp10_channel_estimation_request *mm = buf; mm->version = 0; avail -= sizeof(*mm); return (len - avail); } static int hp10_dump_parameters_stats_confirm(void *buf, int len) { int avail = len; struct hp10_parameters_stats_confirm *mm = buf; faifa_printf(out_stream, "Tx ACK counter: %d\n", (short unsigned int)mm->tx_ack_cnt); faifa_printf(out_stream, "Tx NACK counter: %d\n", (short unsigned int)mm->tx_nack_cnt); faifa_printf(out_stream, "Tx FAIL counter: %d\n", (short unsigned int)mm->tx_fail_cnt); faifa_printf(out_stream, "Tx Contention loss counter: %d\n", (short unsigned int)mm->tx_cont_loss_cnt); faifa_printf(out_stream, "Tx Collision counter: %d\n", (short unsigned int)mm->tx_coll_cnt); faifa_printf(out_stream, "Tx CA3 counter: %d\n", (short unsigned int)mm->tx_ca3_cnt); faifa_printf(out_stream, "Tx CA2 counter: %d\n", (short unsigned int)mm->tx_ca2_cnt); faifa_printf(out_stream, "Tx CA1 counter: %d\n", (short unsigned int)mm->tx_ca1_cnt); faifa_printf(out_stream, "Tx CA0 counter: %d\n", (short unsigned int)mm->tx_ca0_cnt); faifa_printf(out_stream, "Rx cumul (bytes per 40-symbol packet counter: %d\n", (short unsigned int)mm->rx_cumul); avail -= sizeof(*mm); return (len - avail); } static void hp10_dump_tonemap(struct hp10_tonemap *tonemap) { int i; for (i = 0; i < HP10_NUM_TONE_MAP; i++) { faifa_printf(out_stream, "Network DA"); dump_hex(tonemap->netw_da, 6, " "); faifa_printf(out_stream, "\n"); faifa_printf(out_stream, "Number of 40-bytes symbols: %d\n", (short unsigned int)tonemap->bytes40); faifa_printf(out_stream, "Number of failed symbols: %d\n", (short unsigned int)tonemap->fails); faifa_printf(out_stream, "Number of droppe symbols: %d\n", (short unsigned int)tonemap->drops); } } static int hp10_dump_extended_network_stats(void *buf, int len) { int avail = len; struct hp10_network_stats_confirm *mm = buf; faifa_printf(out_stream, "AC flag: %s\n", mm->ac ? "Yes" : "No"); faifa_printf(out_stream, "Number of 40-symbol robo: %d\n", (short unsigned int)mm->bytes40_robo); faifa_printf(out_stream, "Number of failed robo: %d\n", (short unsigned int)mm->fails_robo); faifa_printf(out_stream, "Number of dropped robo: %d\n", (short unsigned int)mm->drops_robo); hp10_dump_tonemap(mm->nstone); avail -= sizeof(*mm); return (len - avail); } struct hp10_frame_ops hp10_frame_ops[] = { { .mmtype = 0x00, .desc = "Channel Estimation Request", .init_frame = hp10_init_channel_estimation_request, }, { .mmtype = 0x01, .desc = "Channel Estimation Confirm", }, { .mmtype = 0x04, .desc = "Set Network Encryption Key Request", .init_frame = init_empty_frame, }, { .mmtype = 0x06, .desc = "Set Network Encryption Key Confirm", }, { .mmtype = 0x07, .desc = "Parameters and Statistics Request", .init_frame = init_empty_frame, }, { .mmtype = 0x08, .desc = "Parameters and Statistics Confirm", .dump_frame = hp10_dump_parameters_stats_confirm, }, { .mmtype = 0x19, .desc = "Set Local parameters Request", .init_frame = init_empty_frame, }, { .mmtype = 0x1a, .desc = "Basic Network Statistics Confirm", }, { .mmtype = 0x1c, .desc = "Extended Network Statistics Confirm", .dump_frame = hp10_dump_extended_network_stats, }, { .mmtype = 0x1d, .desc = "Set Local Overrides Request", .init_frame = init_empty_frame, }, { .mmtype = 0x1e, .desc = "Bridging Characteristics Response", }, { .mmtype = 0x1f, .desc = "Set Transmit Characteristics Request", } }; /** * set_oui - sets the OUI of a frame * @raw: buffer to set the oui to * @oui: value of the oui */ static inline void set_oui(void *raw, u_int8_t *oui) { bcopy(oui, raw, 3); } /** * hpav_mmtype2index - lookup the mmtype and returns the corresponding * index (if found) from the hpav_frame_ops array * @mmtype: mmtype to look for */ static int hpav_mmtype2index(u_int16_t mmtype) { unsigned int i; for (i = 0; i < ARRAY_SIZE(hpav_frame_ops); i++) { if (hpav_frame_ops[i].mmtype == mmtype) return i; } return -1; } /** * hp10_mmtype2index - lookup the mmtype and returns the corresponding * index (if found) from the hp10_frame_ops array * @mmtype: mmtype to look for */ static int hp10_mmtype2index(u_int8_t mmtype) { unsigned int i; for (i = 0; i < ARRAY_SIZE(hp10_frame_ops); i++) { if (hp10_frame_ops[i].mmtype == mmtype) return i; } return -1; } /** * set_init_callback - set the new initialisation callback in frame_ops * @mmtype: mmtype to set the new callback for * @callback: the new callback */ int set_init_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, void *user)) { int i; i = hpav_mmtype2index(mmtype); if (i < 0) return -1; if (callback) hpav_frame_ops[i].init_frame = callback; return 0; } /** * set_dump_callback - set the new dump callback in frame_ops * @mmtype: mmtype to set the new callback for * @callback: the new callback */ int set_dump_callback(u_int16_t mmtype, int (*callback)(void *buf, int len, struct ether_header *hdr)) { int i; i = hpav_mmtype2index(mmtype); if (i < 0) return -1; if (callback) hpav_frame_ops[i].dump_frame = callback; return 0; } /** * ether_init_header - initialize the Ethernet frame header * @buf: buffer to initialize * @len: size of the buffer * @da: destination MAC address (should not be NULL) * @sa: destination MAC address (should not be NULL) * @ethertype: ethertype (between HomePlug 1.0/AV) * @return: number of bytes set in buffer */ int ether_init_header(void *buf, int len, u_int8_t *da, u_int8_t *sa, u_int16_t ethertype) { int avail = len; struct ether_header *header = buf; /* set destination eth addr */ memcpy(header->ether_dhost, da, ETHER_ADDR_LEN); /* set source eth addr */ if (sa != NULL) { memcpy(header->ether_shost, sa, ETHER_ADDR_LEN); } else if (ethertype == ETHERTYPE_HOMEPLUG) { memset(header->ether_shost, 0xFF, ETHER_ADDR_LEN); } else if (ethertype == ETHERTYPE_HOMEPLUG_AV) { memset(header->ether_shost, 0x00, ETHER_ADDR_LEN); } /* Set the ethertype */ header->ether_type = htons(ethertype); avail -= sizeof(*header); return (len - avail); } static char *hpav_get_mmver_str(u_int8_t mmver) { if( mmver == HPAV_VERSION_1_0 ) return "1.0"; else if( mmver == HPAV_VERSION_1_1 ) return "1.1"; else return "Unknown"; } /** * hpav_do_frame - prepare and send a HomePlug AV frame to the network * @frame_buf: data buffer * @frame_len: data buffer length * @mmtype: MM type to send * @da: destination MAC address * @sa: source MAC address * @user: user buffer */ static int hpav_do_frame(void *frame_buf, int frame_len, u_int16_t mmtype, u_int8_t *da, u_int8_t *sa, void *user) { int i, n; struct hpav_frame *frame; u_int8_t *frame_ptr = frame_buf; /* Lookup for the index from the mmtype */ i = hpav_mmtype2index(mmtype); if (i < 0) { faifa_printf(err_stream, "Invalid MM Type %04x\n", (unsigned int)mmtype); return -1; } /* Zero-fill the frame */ bzero(frame_buf, frame_len); /* Check the destination MAC address */ if (da == NULL || faifa_is_zero_ether_addr(da)) da = hpav_intellon_macaddr; /* Set the ethernet frame header */ n = ether_init_header(frame_ptr, frame_len, da, sa, ETHERTYPE_HOMEPLUG_AV); frame_len -= n; frame_ptr += n; frame = (struct hpav_frame *)frame_ptr; n = sizeof(frame->header); frame->header.mmtype = STORE16_LE(mmtype); if( (mmtype & HPAV_MM_CATEGORY_MASK) == HPAV_MM_VENDOR_SPEC ) { frame->header.mmver = HPAV_VERSION_1_0; set_oui(frame->payload.vendor.oui, hpav_intellon_oui); n += sizeof(frame->payload.vendor); } else { frame->header.mmver = HPAV_VERSION_1_1; n += sizeof(frame->payload.public); } frame_len -= n; frame_ptr += n; faifa_printf(out_stream, "Frame: %s (0x%04X)\n", hpav_frame_ops[i].desc, hpav_frame_ops[i].mmtype); /* Call the frame specific setup callback */ if (hpav_frame_ops[i].init_frame != NULL) { n = hpav_frame_ops[i].init_frame(frame_ptr, frame_len, user); frame_ptr += n; frame_len = frame_ptr - (u_int8_t *)frame_buf; } return (frame_len); } /** * hp10_do_frame - prepare and send a HomePlug 1.0 frame to the network * @frame_buf: data buffer * @frame_len: data buffer length * @mmtype: MM type to send * @da: destination MAC address * @sa: source MAC address * @user: user buffer */ static int hp10_do_frame(u_int8_t *frame_buf, int frame_len, u_int8_t mmtype, u_int8_t *da, u_int8_t *sa, void *user) { int i, n; struct hp10_frame *frame; u_int8_t *frame_ptr = frame_buf; /* Lookup for the index from the mmtype */ i = hp10_mmtype2index(mmtype); if (i < 0) { faifa_printf(err_stream, "Invalid MM Type %04x\n", (unsigned int)mmtype); return -1; } /* Zero-fill the frame */ bzero(frame_ptr, frame_len); /* Check the destination MAC address */ if (da == NULL) da = broadcast_macaddr; /* Set the ethernet frame header */ n = ether_init_header(frame_ptr, frame_len, broadcast_macaddr, sa, ETHERTYPE_HOMEPLUG); frame_len -= n; frame_ptr += n; frame = (struct hp10_frame *)frame_ptr; n = sizeof(struct hp10_frame) + sizeof(struct hp10_mmentry); frame_len -= n; frame_ptr += n; /* Initialize the frame header with the specificied mmtype */ frame->mmecount = 1; frame->mmentries[0].mmetype = (u_int8_t)mmtype; frame->mmentries[0].mmeversion = 0; frame->mmentries[0].mmelength = 0; faifa_printf(out_stream, "Frame: 0x%02hX (%s)\n", hp10_frame_ops[i].mmtype, hp10_frame_ops[i].desc); /* Call the frame specific setup callback */ if (hp10_frame_ops[i].init_frame != NULL) { n = hp10_frame_ops[i].init_frame(frame_ptr, frame_len, user); frame_ptr += n; frame_len = frame_ptr - (u_int8_t *)frame_buf; frame->mmentries[0].mmelength += n; } return (frame_len); } /** * do_frame - Send a HomePlug 1.0/AV frame * @mmtype: MM type to send * @da: destination MAC address (NULL for broadcast) * @sa: source MAC address (NULL for broadcast) */ int do_frame(faifa_t *faifa, u_int16_t mmtype, u_int8_t *da, u_int8_t *sa, void *user) { u_int8_t frame_buf[1518]; int frame_len = sizeof(frame_buf); int i; /* Dispatch the frame construction */ if ((i = hpav_mmtype2index(mmtype)) >= 0) frame_len = hpav_do_frame(frame_buf, frame_len, mmtype, da, sa, user); else if ((i = hp10_mmtype2index(mmtype)) >= 0) frame_len = hp10_do_frame(frame_buf, frame_len, mmtype, da, sa, user); if (i < 0) return -1; if (frame_len < ETH_ZLEN) frame_len = ETH_ZLEN; /* Dump the frame on the screen for debugging purposes */ if (faifa->verbose) dump_hex_blob(faifa, frame_buf, frame_len); frame_len = faifa_send(faifa, frame_buf, frame_len); if (frame_len == -1) faifa_printf(err_stream, "Init: error sending frame (%s)\n", faifa_error(faifa)); return frame_len; } /** * hpav_dump_frame - Parse an HomePlug AV frame * @frame_ptr: packet data * @frame_len: packet length */ static int hpav_dump_frame(u_int8_t *frame_ptr, int frame_len, struct ether_header *hdr) { struct hpav_frame *frame = (struct hpav_frame *)frame_ptr; int i; if( (i = hpav_mmtype2index(STORE16_LE(frame->header.mmtype))) < 0 ) { faifa_printf(out_stream, "\nUnknow MM type : %04X\n", frame->header.mmtype); return 0; } faifa_printf(out_stream, "Frame: %s (%04X), HomePlug-AV Version: %s\n", hpav_frame_ops[i].desc, hpav_frame_ops[i].mmtype, hpav_get_mmver_str(frame->header.mmver)); if( (frame->header.mmtype & HPAV_MM_CATEGORY_MASK) == HPAV_MM_VENDOR_SPEC ) { frame_ptr = frame->payload.vendor.data; frame_len -= sizeof(frame->payload.vendor); } else { frame_ptr = frame->payload.public.data; frame_len -= sizeof(frame->payload.public); } /* Call the frame specific dump callback */ if (hpav_frame_ops[i].dump_frame != NULL) frame_ptr += hpav_frame_ops[i].dump_frame(frame_ptr, frame_len, hdr); return (frame_ptr - (u_int8_t *)frame); } /** * hp10_dump_frame - Parse an HomePlug 1.0 frame * @frame_ptr: packet data * @frame_len: packet length */ static int hp10_dump_frame(u_int8_t *frame_ptr, int UNUSED(frame_len)) { struct hp10_frame *frame = (struct hp10_frame *)frame_ptr; unsigned int mmeindex; unsigned int mmecount = frame->mmecount; struct hp10_mmentry *mmentry; int i; frame_ptr += sizeof(struct hp10_frame); for (mmeindex = 0; mmeindex < mmecount; mmeindex++) { mmentry = (struct hp10_mmentry *)frame_ptr; faifa_printf(out_stream, "Frame: 0x%02hX (", (unsigned short int)(mmentry->mmetype)); frame_ptr += sizeof(struct hp10_mmentry); if ((i = hp10_mmtype2index(mmentry->mmetype)) >= 0) { faifa_printf(out_stream, "%s)\n", hp10_frame_ops[i].desc); if (hp10_frame_ops[i].dump_frame != NULL) { hp10_frame_ops[i].dump_frame(mmentry->mmedata, mmentry->mmelength); } } else { faifa_printf(out_stream, "unknown)\n"); } frame_ptr += mmentry->mmelength; } return (frame_ptr - (u_int8_t *)frame); } /** * do_receive_frame - Receive a frame from the network * @args: unused * @hdr: unused * @packet: received packet */ void do_receive_frame(faifa_t *faifa, void *buf, int len, void *UNUSED(user)) { struct ether_header *eth_header = buf; u_int16_t *eth_type = &(eth_header->ether_type); u_int8_t *frame_ptr = (u_int8_t *)buf, *payload_ptr; int frame_len = len, payload_len; payload_ptr = frame_ptr + sizeof(*eth_header); payload_len = frame_len - sizeof(*eth_header); if (*eth_type == ETHERTYPE_8021Q) { payload_ptr += 4; payload_len -= 4; eth_type = (u_int16_t *)(payload_ptr - 2); } /* Check ethertype */ if (!(*eth_type == ntohs(ETHERTYPE_HOMEPLUG)) && !(*eth_type == ntohs(ETHERTYPE_HOMEPLUG_AV))) return; faifa_printf(out_stream, "\nDump:\n"); if (*eth_type == ntohs(ETHERTYPE_HOMEPLUG)) hp10_dump_frame(payload_ptr, payload_len); else if (*eth_type == ntohs(ETHERTYPE_HOMEPLUG_AV)) hpav_dump_frame(payload_ptr, payload_len, eth_header); /* Dump the frame on the screen for debugging purposes */ if (faifa->verbose) dump_hex_blob(faifa, frame_ptr, frame_len); } /** * open_pcap_loop - open a network interface in PCAP loop mode * @arg: unused */ void *receive_loop(faifa_t *faifa) { faifa_loop(faifa, (void *)do_receive_frame, faifa); return faifa; } /** * ask_for_frame - ask the user for a specific mmtype * @mmtype: mmtype to store the user input */ static int ask_for_frame(u_int16_t *mmtype) { unsigned int i; faifa_printf(out_stream, "\nSupported HomePlug AV frames\n\n"); faifa_printf(out_stream, "type description\n"); faifa_printf(out_stream, "------ -----------\n"); for (i = 0; i < ARRAY_SIZE(hpav_frame_ops); i++) { if (hpav_frame_ops[i].init_frame != NULL) { faifa_printf(out_stream, "0x%04X %s\n", hpav_frame_ops[i].mmtype, hpav_frame_ops[i].desc); } } faifa_printf(out_stream, "\nSupported HomePlug 1.0 frames\n\n"); faifa_printf(out_stream, "type description\n"); faifa_printf(out_stream, "------ -----------\n"); for (i = 0; i < ARRAY_SIZE(hp10_frame_ops); i++) { if (hp10_frame_ops[i].init_frame != NULL) { faifa_printf(out_stream, "0x%04X %s\n", (unsigned int)hp10_frame_ops[i].mmtype, hp10_frame_ops[i].desc); } } faifa_printf(out_stream, "\nChoose the frame type (Ctrl-C to exit): 0x"); fscanf(in_stream, "%4x", &i); *mmtype = (u_int16_t)(0xFFFF & i); return (*mmtype != 0xFFFF); } /** * menu - show a menu of the available to send mmtypes */ void menu(faifa_t *faifa) { pthread_t receive_thread; u_int16_t mmtype; /* Create a receiving thread */ if (pthread_create(&receive_thread, NULL, (void *)receive_loop, faifa)) { perror("error creating thread"); abort(); } faifa_printf(out_stream, "Started receive thread\n"); /* Keep asking the user for a mmtype to send */ while (ask_for_frame(&mmtype)) { do_frame(faifa, mmtype, faifa->dst_addr, NULL, NULL); sleep(1); } /* Rejoin the receiving thread */ if (pthread_join(receive_thread, NULL)) { perror("error joining thread"); abort(); } faifa_printf(out_stream, "Closing receive thread\n"); } faifa-0.2~svn82.orig/faifa.h.80000644000175000017500000000757611250716710015757 0ustar drazzibdrazzib.TH FAIFA.H 8 "April 2008" Linux "User manual" .SH NAME faifa.h \- Public interface for the Faifa library .SH DESCRIPTION faifa.h describes the public interface of the faifa library .B Faifa operations Faifa basically performs 3 main operations : - send all vendor and protocol specific frames with the corresponding parameters .br - dump all vendor and HomePlug 1.0/AV frames with the appropriate frame parsing .br - discover the HPAV network topology 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. .B Using the faifa library 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. .B Linking with faifa 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. An example makefile could look like: all: test LIBS:=-lm -ltest -lfaifa $(CC) -D$(OS) $(CFLAGS) -o $@ $(OBJS) $(LIBS) .B Prototypes 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. Most of the functions here are juste wrappers to the PCAP library. .B faifa_t - private handle typedef struct faifa faifa_t; struct faifa { char ifname[IFNAMSIZ]; pcap_t *pcap; char error[256]; }; 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. This structure is initialised on startup of the program. .B faifa_t *faifa_init(void) Initialize the faifa private handle of the library. Returns a private handle on success, NULL on error. This function should be called at the very beginning of your program, i.e : right after parsing command line arguments for instance. .B void faifa_free(faifa_t *faifa) Free the faifa library and dereferences all the private handle members. This function should be called on the error path of your program or while closing it. .B char *faifa_error(faifa_t *faifa); Return a text message related to the last error. .B int faifa_open(faifa_t *faifa, char *name); Open specified network device. Returns 0 on success, -1 on error This function will verify that the interface is an Ethernet link layer interface, that it exists and is up and running. These operations required root or similar priviledges. .B int faifa_close(faifa_t *faifa); Close network device. Returns 0 on success, -1 on error. .B int faifa_send(faifa_t *faifa, void *buf, int len) Send raw ethernet frame on the interface. Returns the number of bytes sent on success, -1 on error. This function will send a raw ethernet frame (see faifa(8) for more informations) therefore letting you total control over the frame you wish to send. Additionnal checks should be performed if your ethernet protocol requires more checkings. .B int faifa_recv(faifa_t *faifa, void *buf, int len) Receive raw ethernet frame. Returns the number of bytes received on success, -1 on error. This function opens the network interface in non-blocking read mode, therefore letting you start another capture program. .B void (*faifa_loop_handler_t)(faifa_t *faifa, void *buf, int len, void *user) Receive and dispatch frames in a loop. This function helps you dispatch received frames to a local function based on the buffer contents. .SH SEE ALSO .BR faifa(8) .SH AUTHOR Florian Fainelli , Xavier Carcelle faifa-0.2~svn82.orig/faifa.80000644000175000017500000001315411562172154015522 0ustar drazzibdrazzib.TH FAIFA 8 "April 2011" Linux "User manual" .SH NAME faifa \- configure HomePlug 1.0/AV devices .SH SYNOPSIS .B faifa [OPTIONS] .br \-i specify network interface to use .br \-m show the menu asking for known MM types .br \-a destination MAC address to send frames to .br \-k network key to set .br \-v be verbose (default: no) .br \-e set error stream (default: stderr) .br \-o set output stream (default: stdout) .br \-s set input stream (default: stdin) .br \-h show the usage .br .SH DESCRIPTION faifa can configure any Intellon-based PowerLine Communication device using the Intellon INT5000 and INT6000 HomePlug AV (200Mbits) chips. It supports all Intellon-specific management and control frames. .SH "MENU COMMANDS" \-i specify network interface to use .br \-m show the menu asking for known MM types .br \-a destination MAC address to send frames to .br \-k network key to set .br \-v be verbose (default: no) .br \-e set error stream (default: stderr) .br \-o set output stream (default: stdout) .br \-s set input stream (default: stdin) .br \-h show the usage .TP .B "HomePlug AV protocol" 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. 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. ------------------------------------ .br | HomePlug PHY | .br ------------------------------------ .br | HomePlug MAC convergence layer | .br ------------------------------------ .br | Ethernet MAC layer | .br ------------------------------------ .br 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. 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. A HomePlug AV management frame is described below : 8 bits 16 bits .br --------------------------------------------------- .br | MM version | MM type | .br --------------------------------------------------- .br | OUI (24 bits) | .br --------------------------------------------------- .br | Payload (var) | .br --------------------------------------------------- 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. .B Faifa operations Faifa basically performs 3 main operations : \- send all vendor and protocol specific frames with the corresponding parameters .br \- dump all vendor and HomePlug 1.0/AV frames with the appropriate frame parsing .br \- discover the HPAV network topology 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. .B Using the faifa library 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. .B Linking with faifa 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. .B Sending frames using do_frame 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 : \- lookup the mmtype by reading the array containing available frame operations .br \- initialize the frame header (MM version, type, source and destination MAC addresses) .br \- call the initialisation function (if needed) to let the user input the parameters (or any other input method) .br \- calculate the appropriate frame size .br \- send it to the device .br \- close the network socket descriptor This function propagates the return code from the write command on the socket descriptor. .B Receiving frames using do_receive_frame This function will listen for received frames on the specified interface and will : \- check that the ethertype is set to 0x88e1 otherwise it will discard the frame .br \- cast the received packet to an HPAV management frame structure .br \- lookup for the received MM type into the arrays of known response/indications .br \- call the frame parsing function (based on the mmtype) accordingly 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. .SH SEE ALSO .BR ifconfig(8) .SH AUTHORS Florian Fainelli , Xavier Carcelle , Nicolas Thill faifa-0.2~svn82.orig/configure.in0000644000175000017500000000332711270637167016703 0ustar drazzibdrazzibAC_INIT(faifa, 0.2) AC_PREREQ(2.59) AC_PROG_CC AC_PROG_RANLIB AC_PROG_INSTALL PA_ADD_CFLAGS(-Wall) # Basic headers AC_CHECK_HEADERS(stdio.h) AC_CHECK_HEADERS(stdlib.h) AC_CHECK_HEADERS(unistd.h) AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(arpa/inet.h) AC_CHECK_HEADERS(errno.h) AC_CHECK_HEADERS(stdarg.h) AC_CHECK_HEADERS(string.h) AC_CHECK_HEADERS(net/if.h) # Libraries provided headers AC_CHECK_HEADERS([pthread.h],,[AC_MSG_ERROR([You need libpthread development files])]) AC_CHECK_HEADERS([pcap.h],,[AC_MSG_ERROR([You need libpcap development files])]) AC_CHECK_HEADERS([openssl/sha.h],,[AC_MSG_ERROR([You need openssl development files])]) # Check libraries AC_CHECK_LIB(pthread, pthread_create, [AC_CHECK_LIB(pthread, pthread_join,[LIBS="${LIBS} -lpthread"], AC_MSG_ERROR(You need pthread_join check your libpthread))], AC_MSG_ERROR(You need pthread_create check your libpthread)) AC_CHECK_LIB(pcap, pcap_lookupdev, [AC_CHECK_LIB(pcap, pcap_datalink, [AC_CHECK_LIB(pcap, pcap_next_ex, [AC_CHECK_LIB(pcap, pcap_sendpacket, [AC_CHECK_LIB(pcap, pcap_close, ,AC_MSG_ERROR(You need pcap_close check your libpcap))], AC_MSG_ERROR(You need pcap_sendpacket check your libpcap))], AC_MSG_ERROR(You need pcap_next_ex check your libpcap))], AC_MSG_ERROR(You need pcap_datalink check your libpcap))], AC_MSG_ERROR(You need pcap_lookupdev check your libpcap)) AC_CHECK_LIB([crypto], [SHA256_Init], [AC_CHECK_LIB([crypto], [SHA256_Update], [AC_CHECK_LIB([crypto], [SHA256_Final],LIBS="${LIBS} -lcrypto", AC_MSG_ERROR(you need SHA256_Final check your libcrypto))], AC_MSG_ERROR(you need SHA256_Update check your libcrypto))], AC_MSG_ERROR(you need SHA256_Update check your libcrypto)) AC_CONFIG_HEADER(config.h) AC_OUTPUT(Makefile) faifa-0.2~svn82.orig/main.c0000644000175000017500000001135211546610111015441 0ustar drazzibdrazzib/* * Program entry and command line parsing * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include #include #include "faifa.h" #include "faifa_compat.h" #ifndef FAIFA_PROG #define FAIFA_PROG "faifa" #endif /* Command line arguments storing */ int opt_help = 0; int opt_interactive = 0; int opt_key = 0; extern FILE *err_stream; extern FILE *out_stream; extern FILE *in_stream; /** * error - display error message */ static void error(char *message) { fprintf(stderr, "%s: %s\n", FAIFA_PROG, message); } /** * usage - show the program usage */ static void usage(void) { fprintf(stderr, "-i : interface\n" "-m : show menu (no option required)\n" "-a : station MAC address\n" "-k : network key\n" "-v : be verbose (default: no)\n" "-e : error stream (default: stderr)\n" "-o : output stream (default: stdout)\n" "-s : input stream (default: stdin)\n" "-h : this help\n"); } extern void menu(faifa_t *faifa); extern void set_key(char *macaddr); /** * main - main function of faifa * @argc: number of arguments * @argv: array of arguments */ int main(int argc, char **argv) { faifa_t *faifa; char *opt_ifname = NULL; char *opt_macaddr = NULL; char *opt_err_stream = NULL; char *opt_out_stream = NULL; char *opt_in_stream = NULL; int opt_verbose = 0; int c; int ret = 0; u_int8_t addr[ETHER_ADDR_LEN] = { 0 }; fprintf(stdout, "Faifa for HomePlug AV (SVN revision %d)\n\n", SVN_REV); if (argc < 2) { usage(); return -1; } while ((c = getopt(argc, argv, "i:ma:k:ve:o:s:h")) != -1) { switch (c) { case 'i': opt_ifname = optarg; break; case 'm': opt_interactive = 1; break; case 'a': opt_macaddr = optarg; break; case 'k': opt_key = 1; break; case 'v': opt_verbose = 1; break; case 'e': opt_err_stream = optarg; break; case 'o': opt_out_stream = optarg; break; case 's': opt_in_stream = optarg; break; case 'h': default: opt_help = 1; break; } } if (opt_help) { usage(); return -1; } if (opt_ifname == NULL) opt_ifname = "eth0"; if (opt_err_stream == NULL) err_stream = stderr; else { err_stream = fopen(opt_err_stream, "w+"); if (!err_stream) { perror("err_stream"); return -1; } } if (opt_out_stream == NULL) out_stream = stdout; else { out_stream = fopen(opt_out_stream, "w+"); if (!out_stream) { perror("out_stream"); return -1; } } if (opt_in_stream == NULL) in_stream = stdin; else { in_stream = fopen(opt_in_stream, "rb"); if (!in_stream) { perror("in_stream"); return -1; } } faifa = faifa_init(); if (faifa == NULL) { error("can't initialize Faifa library"); return -1; } if (faifa_open(faifa, opt_ifname) == -1) { error(faifa_error(faifa)); faifa_free(faifa); return -1; } faifa_set_verbose(faifa, opt_verbose); if (opt_macaddr) { ret = faifa_parse_mac_addr(faifa, opt_macaddr, addr); if (ret < 0) { error(faifa_error(faifa)); goto out_error; } faifa_set_dst_addr(faifa, addr); } if (opt_interactive) menu(faifa); out_error: faifa_close(faifa); faifa_free(faifa); return ret; } faifa-0.2~svn82.orig/install-sh0000755000175000017500000001273611270073556016376 0ustar drazzibdrazzib#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 faifa-0.2~svn82.orig/faifa.h0000644000175000017500000001102111546672720015577 0ustar drazzibdrazzib/* * Faifa library public interface * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __FAIFA_H__ #define __FAIFA_H__ #include #define FAIFA_VERSION_MAJOR 0 #define FAIFA_VERSION_MINOR 1 #define faifa_printf(stream, fmt,args...) \ fprintf (stream, fmt ,##args) \ #ifdef __cplusplus extern "C" { #endif /** * faifa_t - private handle */ typedef struct faifa faifa_t; /** * faifa_init - init library * @return * private handle on success, NULL on error */ extern faifa_t *faifa_init(void); /** * faifa_free - free library * @faifa: private handle */ extern void faifa_free(faifa_t *faifa); /** * faifa_error - return a text message related to the last error * @faifa: private handle * @return * error message string */ extern char *faifa_error(faifa_t *faifa); /** * faifa_open - open specified network device * @faifa: private handle * @name: network device name * @return * 0 on success, -1 on error */ extern int faifa_open(faifa_t *faifa, char *name); /** * faifa_close - close network device * @faifa: private handle * @return * 0 on success, -1 on error */ extern int faifa_close(faifa_t *faifa); /** * faifa_send - send raw ethernet frame * @faifa: private handle * @buf: data buffer * @len: data buffer length * @return * number of bytes sent on success, -1 on error */ extern int faifa_send(faifa_t *faifa, void *buf, int len); /** * faifa_recv - receive raw ethernet frame * @faifa: private handle * @buf: data buffer * @len: data buffer length * @return * number of bytes received on success, -1 on error */ extern int faifa_recv(faifa_t *faifa, void *buf, int len); /** * faifa_loop_handler_t - packet dispatch handler */ typedef void (*faifa_loop_handler_t)(faifa_t *faifa, void *buf, int len, void *user); /** * faifa_loop - receive and dispatch frames in a loop * @faifa: private handle * @handler: frame dispatch handler * @user: user value passed to the dispatch handler * @return * 0 on success, -1 on error */ extern int faifa_loop(faifa_t *faifa, faifa_loop_handler_t handler, void *user); extern int faifa_sprint_hex(char *str, void *buf, int len, char *sep); /** * faifa_parse_mac_addr - parses a MAC address * @faifa: private handle * @mac: mac address as a string * @addr: mac address as a 6-bytes buffer * @return * 0 on success, -1 on error */ extern int faifa_parse_mac_addr(faifa_t *faifa, const char *mac, u_int8_t *addr); /** * faifa_set_dst_addr - sets the destination MAC address * @faifa: private handle * @mac: destination MAC address * */ extern void faifa_set_dst_addr(faifa_t *faifa, const u_int8_t *addr); /** * faifa_set_verbose - set the faifa verbosity * @faifa: private handle * @verbose: verbosity level */ extern void faifa_set_verbose(faifa_t *faifa, int verbose); static inline int faifa_is_zero_ether_addr(const u_int8_t *addr) { return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); } #ifdef __cplusplus } #endif #endif /* __FAIFA_H__ */ faifa-0.2~svn82.orig/faifa_priv.h0000644000175000017500000000457211546610111016636 0ustar drazzibdrazzib/* * Faifa library private interface * * Copyright (C) 2007-2008 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __FAIFA_PRIV_H__ #define __FAIFA_PRIV_H__ #include #include #include #ifdef DARWIN #include #include #endif #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #ifndef UNUSED # if defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) # elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x # else # define UNUSED(x) x # endif #endif #ifdef __cplusplus extern "C" { #endif struct faifa { char ifname[IFNAMSIZ]; pcap_t *pcap; char error[256]; u_int8_t dst_addr[ETHER_ADDR_LEN]; int verbose; }; extern void faifa_set_error(faifa_t *faifa, char *format, ...); #ifdef __cplusplus } #endif #endif /* __FAIFA_PRIV_H__ */ faifa-0.2~svn82.orig/crypto.c0000644000175000017500000000777311355357670016071 0ustar drazzibdrazzib/* * Cryptographic routines for faifa using OpenSSL * * Copyright (C) 2008 Florian Fainelli * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include #include #include #include "crypto.h" #define HASH_SIZ SHA256_DIGEST_LENGTH unsigned char hash_value[HASH_SIZ]; u_int8_t dak_salt[SALT_SIZ] = {0x08, 0x85, 0x6D, 0xAF, 0x7C, 0xF5, 0x81, 0x85}; u_int8_t nmk_salt[SALT_SIZ] = {0x08, 0x85, 0x6D, 0xAF, 0x7C, 0xF5, 0x81, 0x86}; /** * init_salted_secret - initialise a secret using a salt * @secret: secret to initialise will be modified * @isecret: initialisation secret * @salt: secret to initialise with */ void init_salted_secret(struct salted_secret *secret, const unsigned char *isecret, const unsigned char *isalt) { unsigned char l = ' '; secret->len = 0; memset(secret->value, 0, sizeof(secret->value)); if (isecret) { l = (unsigned char)strlen((char *)isecret); if (l > MAX_SECRET_SIZ) l = MAX_SECRET_SIZ; memcpy(secret->value, (unsigned char *)isecret, l); } if (!isalt) l = 16; secret->len = (unsigned char) (secret->len + l); if (isalt) { memcpy(&secret->value[secret->len], (unsigned char*)isalt, SALT_SIZ); secret->len += SALT_SIZ; } } /** * hash_hpav - hash a secret with a salt as HomePlug AV requires it * @isecret: initialisation secret * @salt: salt to initialise the secret with */ const unsigned char* hash_hpav(const unsigned char* isecret, const unsigned char *salt) { SHA256_CTX context; struct salted_secret secret; int i, max; /* Null salt is the NetworkID */ if (!salt) max = 4; else max = 999; SHA256_Init(&context); memset(hash_value, 0, sizeof(hash_value)); init_salted_secret(&secret, isecret, salt); SHA256_Update(&context, secret.value, secret.len); SHA256_Final(hash_value, &context); /* Do it 998 times as the standard requires it * or only 4 times if we use the NID */ for(i = 0; i < max; i++) { SHA256_Init(&context); SHA256_Update(&context, hash_value, HASH_SIZ); SHA256_Final(hash_value, &context); } return hash_value; } int gen_passphrase(const char *password, u_int8_t *key, const unsigned char *salt) { unsigned char password_cpy[MAX_SECRET_SIZ + 1]; const unsigned char *password_hash; /* Use a local variable to store the input password */ memcpy((unsigned char *)password_cpy, password, MAX_SECRET_SIZ); password_hash = (const unsigned char *)malloc(HASH_SIZ); if (!password_hash) { perror("malloc"); return -1; } password_hash = hash_hpav(password_cpy, salt); memcpy(key, password_hash, 16); return 0; } faifa-0.2~svn82.orig/faifa_compat.h0000644000175000017500000000516411546536253017155 0ustar drazzibdrazzib/* * Faifa library compatibility layer * * Copyright (C) 2007-2009 Xavier Carcelle * Florian Fainelli * Nicolas Thill * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef __FAIFA_COMPAT_H__ #define __FAIFA_COMPAT_H__ #ifndef ETHERTYPE_8021Q # define ETHERTYPE_8021Q 0x8100 #endif #define ETH_ZLEN 60 /* Min. octets in frame w/o FCS */ #ifdef __CYGWIN__ #define PCAP_SRC_IF_STRING "rpcap://" #define ETH_ALEN 6 #define ETHER_CRC_LEN 4 #define ETH_FRAME_LEN 1514 #define ETHER_ADDR_LEN ETH_ALEN #define ETHER_MAX_LEN (ETH_FRAME_LEN + ETHER_CRC_LEN) /* max packet length */ /* This is a name for the 48 bit ethernet address available on many * systems. */ struct ether_addr { u_int8_t ether_addr_octet[ETH_ALEN]; } __attribute__ ((__packed__)); /* 10Mb/s ethernet header */ struct ether_header { u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */ u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */ u_int16_t ether_type; /* packet type ID field */ } __attribute__ ((__packed__)); #else #include #endif #endif /* __FAIFA_COMPAT_H__ */