author | viric@mandarina |
Mon, 28 Apr 2008 21:37:16 +0200 | |
changeset 89 | 2692e4742267 |
parent 88 | a7f546938313 |
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 { |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
31 |
ETH_SERVER_PROTO = 0xCACA, |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
32 |
ETH_CLIENT_PROTO = 0xCACC |
43
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 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
35 |
static int fd; |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
36 |
static enum Eth_type eth_type; |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
37 |
static char srcaddr[6]; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
38 |
static int debug = 0; |
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 |
static void dump(unsigned char *buf, int len) |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
41 |
{ |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
42 |
int i; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
43 |
for(i=0; i < len; ++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 |
printf("%x ", (int) buf[i]); |
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 |
putchar('\n'); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
48 |
} |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
49 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
50 |
// return the index of device 'name' |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
51 |
static int getindx(int s, char *name) |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
52 |
{ |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
53 |
struct ifreq xx; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
54 |
int n; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
55 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
56 |
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
|
57 |
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
|
58 |
n = ioctl(s, SIOCGIFINDEX, &xx); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
59 |
if (n == -1) |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
60 |
return -1; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
61 |
return xx.ifr_ifindex; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
62 |
} |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
63 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
64 |
// get us a raw connection to an interface |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
65 |
int eth_open(char *eth, enum Eth_type type) |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
66 |
{ |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
67 |
int i, n; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
68 |
struct sockaddr_ll sa; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
69 |
struct ifreq xx; |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
70 |
short int proto_num; |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
71 |
|
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
72 |
if (type == ETH_SERVER) |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
73 |
{ |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
74 |
dump_line("eth_open for server\n"); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
75 |
proto_num = htons(ETH_SERVER_PROTO); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
76 |
} |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
77 |
else if (type == ETH_CLIENT) |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
78 |
{ |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
79 |
dump_line("eth_open for client\n"); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
80 |
proto_num = htons(ETH_CLIENT_PROTO); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
81 |
} |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
82 |
else |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
83 |
return -1; |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
84 |
|
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
85 |
/* Note the type server or client for this process */ |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
86 |
eth_type = type; |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
87 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
88 |
memset(&sa, 0, sizeof sa); |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
89 |
fd = socket(PF_PACKET, SOCK_DGRAM, proto_num); |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
90 |
if (fd == -1) { |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
91 |
perror("got bad socket"); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
92 |
return -1; |
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 |
i = getindx(fd, eth); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
95 |
sa.sll_family = AF_PACKET; |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
96 |
sa.sll_protocol = proto_num; |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
97 |
sa.sll_ifindex = i; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
98 |
n = bind(fd, (struct sockaddr *)&sa, sizeof sa); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
99 |
if (n == -1) { |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
100 |
perror("bind funky"); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
101 |
return -1; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
102 |
} |
44 | 103 |
strncpy(xx.ifr_name, eth, sizeof(xx.ifr_name)); |
104 |
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
|
105 |
n = ioctl(fd, SIOCGIFHWADDR, &xx); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
106 |
if (n == -1) { |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
107 |
perror("Can't get hw addr"); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
108 |
return -1; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
109 |
} |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
110 |
memmove(srcaddr, xx.ifr_hwaddr.sa_data, 6); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
111 |
return fd; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
112 |
} |
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 |
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
|
115 |
{ |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
116 |
struct sockaddr_ll sa; |
44 | 117 |
int sa_len = sizeof(sa); |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
118 |
int res; |
66
b2469563a1dc
Reliable ethernet protocol. I still need pselect instead of select.
viric@mandarina
parents:
53
diff
changeset
|
119 |
dump_line("eth_recv\n"); |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
120 |
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
|
121 |
if (debug) { |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
122 |
printf("read %d bytes\r\n", res); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
123 |
dump(buf, res); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
124 |
} |
44 | 125 |
/* Assume sa_len will be ok */ |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
126 |
if (partner_mac) |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
127 |
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
|
128 |
return res; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
129 |
} |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
130 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
131 |
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
|
132 |
{ |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
133 |
struct sockaddr_ll sa; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
134 |
int i; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
135 |
|
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
136 |
i = getindx(fd, dev); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
137 |
sa.sll_family = AF_PACKET; |
87
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
138 |
if (eth_type == ETH_SERVER) |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
139 |
{ |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
140 |
dump_line("eth_send from server to client\n"); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
141 |
sa.sll_protocol = htons(ETH_CLIENT_PROTO); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
142 |
} |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
143 |
else if (eth_type == ETH_CLIENT) |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
144 |
{ |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
145 |
dump_line("eth_send from client to server\n"); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
146 |
sa.sll_protocol = htons(ETH_SERVER_PROTO); |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
147 |
} |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
148 |
else |
be4ee314545c
Making client and server use different ethernet protocols
viric@llimona
parents:
66
diff
changeset
|
149 |
return -1; |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
150 |
sa.sll_ifindex = i; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
151 |
sa.sll_halen = 6; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
152 |
memcpy(sa.sll_addr, mac, 6); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
153 |
if (debug) { |
88 | 154 |
printf("sending %d bytes to eth_protocol %hi\r\n", len, sa.sll_protocol); |
43
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
155 |
dump(p, len); |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
156 |
} |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
157 |
if (len > 1500) |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
158 |
len = 1500; |
625794738afc
Added first attempt for an ethernet protocol. Even not tried.
viric@llimona
parents:
diff
changeset
|
159 |
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
|
160 |
} |