eth_linux.c
author viric@llimona
Mon, 08 Oct 2007 12:59:27 +0200
changeset 79 7d316733d4b1
parent 66 b2469563a1dc
child 87 be4ee314545c
permissions -rw-r--r--
Added filterdes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     1
/* Copyright Coraid, Inc. 2006.  All rights reserved. */
53
07500c5c53cb Adding license and web html.
viric@llimona
parents: 44
diff changeset
     2
/* Modified the original with BSD license by Lluis Batlle */
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     3
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     4
#include <sys/types.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     5
#include <sys/socket.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     6
#include <stdio.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     7
#include <string.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     8
#include <stdlib.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
     9
#include <unistd.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    10
#include <sys/time.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    11
#include <features.h>    /* for the glibc version number */
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    12
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    13
#include <netpacket/packet.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    14
#include <net/ethernet.h>     /* the L2 protocols */
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    15
#else
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    16
#include <asm/types.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    17
#include <linux/if_packet.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    18
#include <linux/if_ether.h>   /* The L2 protocols */
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    19
#endif
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    20
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    21
#include <sys/ioctl.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    22
#include <net/if.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    23
#include <netinet/in.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    24
#include <linux/fs.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    25
#include <sys/stat.h>
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    26
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 53
diff changeset
    27
#include "main.h"
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    28
#include "eth_linux.h"
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    29
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    30
enum {
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    31
    ETH_PROTO = 0xCACA
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    32
};
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    33
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    34
static int fd;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    35
static char srcaddr[6];
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    36
static int debug = 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    37
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    38
static void dump(unsigned char *buf, int len)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    39
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    40
  int i;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    41
  for(i=0; i < len; ++i)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    42
  {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    43
    printf("%x ", (int) buf[i]);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    44
  }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    45
  putchar('\n');
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    46
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    47
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    48
// return the index of device 'name'
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    49
static int getindx(int s, char *name)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    50
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    51
    struct ifreq xx;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    52
    int n;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    53
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    54
    strncpy(xx.ifr_name, name, sizeof(xx.ifr_name));
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    55
    xx.ifr_name[sizeof(xx.ifr_name)-1] = 0;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    56
    n = ioctl(s, SIOCGIFINDEX, &xx);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    57
    if (n == -1)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    58
        return -1;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    59
    return xx.ifr_ifindex;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    60
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    61
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    62
// get us a raw connection to an interface
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    63
int eth_open(char *eth)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    64
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    65
    int i, n;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    66
    struct sockaddr_ll sa;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    67
    struct ifreq xx;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    68
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    69
    memset(&sa, 0, sizeof sa);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    70
    fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_PROTO));
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    71
    if (fd == -1) {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    72
        perror("got bad socket");
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    73
        return -1;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    74
    }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    75
    i = getindx(fd, eth);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    76
    sa.sll_family = AF_PACKET;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    77
    sa.sll_protocol = htons(ETH_PROTO);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    78
    sa.sll_ifindex = i;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    79
    n = bind(fd, (struct sockaddr *)&sa, sizeof sa);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    80
    if (n == -1) {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    81
        perror("bind funky");
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    82
        return -1;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    83
    }
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    84
    strncpy(xx.ifr_name, eth, sizeof(xx.ifr_name));
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    85
    xx.ifr_name[sizeof(xx.ifr_name)-1] = 0;
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    86
    n = ioctl(fd, SIOCGIFHWADDR, &xx);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    87
    if (n == -1) {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    88
        perror("Can't get hw addr");
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    89
        return -1;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    90
    }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    91
    memmove(srcaddr, xx.ifr_hwaddr.sa_data, 6);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    92
    return fd;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    93
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    94
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    95
int eth_recv(char *buf, int len, char *partner_mac)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    96
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    97
    struct sockaddr_ll sa;
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
    98
    int sa_len = sizeof(sa);
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
    99
    int res;
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 53
diff changeset
   100
    dump_line("eth_recv\n");
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   101
    res = recvfrom(fd, buf, len, 0, (struct sockaddr *) &sa, &sa_len);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   102
    if (debug) {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   103
        printf("read %d bytes\r\n", res);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   104
        dump(buf, res);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   105
    }
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   106
    /* Assume sa_len will be ok */
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   107
    if (partner_mac)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   108
        memcpy(partner_mac, sa.sll_addr, sa.sll_halen);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   109
    return res;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   110
}
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   111
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   112
int eth_send(char *dev, char *mac, void *p, int len)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   113
{
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   114
    struct sockaddr_ll sa;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   115
    int i;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   116
66
b2469563a1dc Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents: 53
diff changeset
   117
    dump_line("eth_send\n");
44
41241a0f84bf Almost fixed eth transport.
viric@llimona
parents: 43
diff changeset
   118
43
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   119
    i = getindx(fd, dev);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   120
    sa.sll_family = AF_PACKET;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   121
    sa.sll_protocol = htons(ETH_PROTO);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   122
    sa.sll_ifindex = i;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   123
    sa.sll_halen = 6;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   124
    memcpy(sa.sll_addr, mac, 6);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   125
    if (debug) {
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   126
        printf("sending %d bytes\r\n", len);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   127
        dump(p, len);
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   128
    }
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   129
    if (len > 1500)
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   130
        len = 1500;
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   131
    return sendto(fd, p, len, 0, (struct sockaddr*) &sa, sizeof(sa));
625794738afc Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff changeset
   132
}