author | viric@llimona |
Mon, 08 Oct 2007 12:59:27 +0200 | |
changeset 79 | 7d316733d4b1 |
parent 66 | b2469563a1dc |
child 87 | be4ee314545c |
permissions | -rw-r--r-- |
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 | 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 | 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 | 84 |
strncpy(xx.ifr_name, eth, sizeof(xx.ifr_name)); |
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 | 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 | 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 | 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 |
} |