plc(Power Line Communication)通信测试程序

本文介绍了使用plc(Power Line Communication)进行通信的测试程序,包括涉及的源代码plconfig.c及其依赖的MD5头文件,探讨了PLC通信的基础和应用。
摘要由CSDN通过智能技术生成

plc(Power Line Communication)通信测试程序
plconfig.c

/*
    plconfig.c version 0.2
    Source code for Intellon-based Powerline bridge configuration tool

    Copyright (C) 2002-2003 Manuel Kasper <mk@neon1.net>.
    All rights reserved.
*/

/*
 *  Linux specific code by Enrik Berkhan <enrik.berkhan@inka.de>
 *  Copyright (C) 2004 Manuel Kasper <mk@neon1.net>.
 */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>

#ifdef LINUX
#include <linux/types.h>
#include <netinet/in.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <string.h>
#include <signal.h>
#else
#include <net/bpf.h>
#endif

#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "global.h"
#include "md5.h"

#define PLCONFIG_VERSION "0.2"
#define ETHERTYPE_INTELLON  0x88E1

#define logictostr(x) (x) ? "yes" : "no"

#ifndef LINUX
/* bpf instructions to filter for Intellon ethertype packets */
struct bpf_insn insns[] = {
     BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
     BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_INTELLON, 0, 1),
     BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
     BPF_STMT(BPF_RET+BPF_K, 0)
};
#endif

u_short ex_word(u_char *ptr) {
    return ntohs(*((u_short*)ptr));
}

u_long ex_long(u_char *ptr) {
    return ntohl(*((u_long*)ptr));
}

char *format_mac_addr(u_char *addr, char *macbuf) {

    sprintf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x",
        addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);

    return macbuf;
}

void dump_params_and_stats(u_char *macmgmt) {

    printf("  Tx ACK Counter:             %u\n"
           "  Tx NACK Counter:            %u\n"
           "  Tx FAIL Counter:            %u\n"
           "  Tx Contention Loss Counter: %u\n"
           "  Tx Collision Counter:       %u\n"
           "  Tx CA3 Latency Counter:     %u\n"
           "  Tx CA2 Latency Counter:     %u\n"
           "  Tx CA1 Latency Counter:     %u\n"
           "  Tx CA0 Latency Counter:     %u\n"
           "  Rx Cumul. Bytes per 40-symbol Packet Counter: %lu\n",

           ex_word(&macmgmt[2]), ex_word(&macmgmt[4]), ex_word(&macmgmt[6]),
           ex_word(&macmgmt[8]), ex_word(&macmgmt[10]), ex_word(&macmgmt[12]),
           ex_word(&macmgmt[14]), ex_word(&macmgmt[16]), ex_word(&macmgmt[18]),
           ex_long(&macmgmt[20]));
}

void dump_network_statistics(u_char *macmgmt) {

    int     da;
    u_char  *stat;
    char    macbuf[20];

    for (da = 0; da < 15; da++) {

        stat = (macmgmt+9+da*12);

        /* Check to see if that node entry is valid -
           stupid Intellon chip is supposed to return 00:00:00:00:00:00 for
           nonexistant nodes (as per the specs), but instead it returns
           01:00:00:00:00:00 so we just skip checking the first byte,
           since heaven knows what else it may return instead of 01 in
           other places/revisions.
        */

        if (!((stat[1] == 0) && (stat[2] == 0) &&
              (stat[3] == 0) && (stat[4] == 0) && (stat[5] == 0))) {

            printf("\n  Statistics for Network DA #%d:\n"
                   "  MAC address:         %s\n"
                   "  Bytes in 40 symbols: %u\n"
                   "  FAILS received:      %u\n"
                   "  Frame Drops:         %u\n",

                   da+1, format_mac_addr(stat, macbuf), ex_word(&stat[6]),
                   ex_word(&stat[8]), ex_word(&stat[10])); 
        }
    }
}

void dump_tx_characteristics(u_char *macmgmt) {

    char *retrtab[] = {
  "Transmit without retries",
        "Transmit with one retry only",
        "Transmit with normal retries (HomePlug)", "Reserved"};

    printf("  Local consumption only:        %s\n"
           "  Encryption flag:               %s\n"
           "  Transmit priority:             %u\n"
           "  Response expected:             %s\n"
           "  Transmit contention free:      %s\n"
           "  Retry control:                 %s\n"
           "  No default encryption receive: %s\n"
           "  No unencrypted receive:        %s\n"
           "  Transmit EKS:                  %u\n",

           logictostr(macmgmt[2] & 0x80), logictostr(macmgmt[2] & 0x40),
           (macmgmt[2] >> 4) & 0x03, logictostr(macmgmt[2] & 0x08), 
           logictostr(macmgmt[2] & 0x04), retrtab[(macmgmt[3] >> 6) & 0x03],
           logictostr(macmgmt[3] & 0x08), logictostr(macmgmt[3] & 0x04),
           macmgmt[4]);
}

void dump_set_key(u_char *macmgmt) {

    char    asckey[17];
    char    *hextab = "0123456789abcdef";
    int     i;

    /* Convert the key to ASCII hex */
    for (i = 0; i < 8; i++) {
        asckey[i<<1] = hextab[(macmgmt[i+3] >> 4) & 0x0F];
        asckey[(i<<1)+1] = hextab[macmgmt[i+3] & 0x0F];
    }

    asckey[16] = 0;

    printf("  Encryption key select:  0x%02x\n"
           "  Network encryption key: %s\n",

           macmgmt[2], asckey); 

}

void read_display_responses(int netfd, u_char *framebuf, u_int buflen) {

    u_char  *frameptr;
    ssize_t rdlen;
    u_int   i, j;
#ifdef LINUX
    struct sockaddr_ll addr;
    socklen_t addrlen = sizeof(addr);
#else
    struct bpf_hdr *header;
#endif
    char macbuf[20];

    /* read responses */
    while (1) {
#ifdef LINUX
        rdlen = recvfrom(netfd, framebuf+ETHER_HDR_LEN, buflen-ETHER_HDR_LEN, MSG_TRUNC, (struct sockaddr *)&addr, &addrlen);
#else
        rdlen = read(netfd, framebuf, buflen);
#endif

        if (rdlen != -1) {

#ifdef LINUX
            if (rdlen > buflen-ETHER_HDR_LEN) {
                fprintf(stderr, "received jumbo frame of %d bytes len, truncated\n", rdlen);
            }
            frameptr = framebuf;
            memcpy(framebuf+6, &addr.sll_addr, 6);

            if (addr.sll_pkttype != PACKET_OUTGOING &&
                addr.sll_protocol == htons(ETHERTYPE_INTELLON)) {
#else
            header = (struct bpf_hdr*)framebuf;
            frameptr = framebuf + header->bh_hdrlen;

            if ((frameptr[12] == 0x88) && (frameptr[13] == 0x7B)) {
#endif

                /* It's an intellon packet - read MAC management entries */
                j = 15;

                for (i = 0; i < (frameptr[14] & (u_int)0x7F); i++) {
                    switch (frameptr[j]) {

                        case 0x04:      /* Set Network Encryption Key */
                            printf("\n- Set Network Encryption Key from %s\n",
                                format_mac_addr(&frameptr[6], macbuf));

                            dump_set_key(&frameptr[j]);
                            break;

                        case 0x07:      /* Request Parameters and Statistics */
                            printf("\n- Parameters and Statistics request from %s\n",
                                format_mac_addr(&frameptr[6], macbuf));
                            break;

                        case 0x08:      /* Parameters and Statistics Respo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值