diff options
author | David Brodski <david@brodski.eu> | 2011-11-02 09:59:51 +0000 |
---|---|---|
committer | David Brodski <david@brodski.eu> | 2011-11-02 09:59:51 +0000 |
commit | f81e6c6e4b49b3556ed6a2b7d00803c9db02195c (patch) | |
tree | 7aa745ec7db6c31254147cea6c2b9b327494dff7 | |
parent | 5a4447b2b27be60dde50c77562cbe9dacb453709 (diff) | |
download | gnunet-f81e6c6e4b49b3556ed6a2b7d00803c9db02195c.tar.gz gnunet-f81e6c6e4b49b3556ed6a2b7d00803c9db02195c.zip |
added send test
-rw-r--r-- | src/transport/gnunet_wlan_sender.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/transport/gnunet_wlan_sender.c b/src/transport/gnunet_wlan_sender.c new file mode 100644 index 000000000..a400136da --- /dev/null +++ b/src/transport/gnunet_wlan_sender.c | |||
@@ -0,0 +1,251 @@ | |||
1 | |||
2 | #include <sys/types.h> | ||
3 | #include <unistd.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | |||
7 | #define WLAN_MTU 1500 | ||
8 | |||
9 | #include <sys/socket.h> | ||
10 | #include <sys/ioctl.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <unistd.h> | ||
13 | #include <sys/wait.h> | ||
14 | #include <sys/time.h> | ||
15 | #include <sys/stat.h> | ||
16 | #include <netpacket/packet.h> | ||
17 | #include <linux/if_ether.h> | ||
18 | #include <linux/if.h> | ||
19 | #include <linux/wireless.h> | ||
20 | #include <netinet/in.h> | ||
21 | #include <linux/if_tun.h> | ||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | #include <stdarg.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <errno.h> | ||
28 | #include <dirent.h> | ||
29 | //#include <sys/utsname.h> | ||
30 | #include <sys/param.h> | ||
31 | |||
32 | #include <time.h> | ||
33 | |||
34 | |||
35 | #include "gnunet/gnunet_protocols.h" | ||
36 | #include "plugin_transport_wlan.h" | ||
37 | |||
38 | /** | ||
39 | * LLC fields for better compatibility | ||
40 | */ | ||
41 | #define WLAN_LLC_DSAP_FIELD 0x1f | ||
42 | #define WLAN_LLC_SSAP_FIELD 0x1f | ||
43 | |||
44 | #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ | ||
45 | |||
46 | #define IEEE80211_FC0_VERSION_MASK 0x03 | ||
47 | #define IEEE80211_FC0_VERSION_SHIFT 0 | ||
48 | #define IEEE80211_FC0_VERSION_0 0x00 | ||
49 | #define IEEE80211_FC0_TYPE_MASK 0x0c | ||
50 | #define IEEE80211_FC0_TYPE_SHIFT 2 | ||
51 | #define IEEE80211_FC0_TYPE_MGT 0x00 | ||
52 | #define IEEE80211_FC0_TYPE_CTL 0x04 | ||
53 | #define IEEE80211_FC0_TYPE_DATA 0x08 | ||
54 | |||
55 | |||
56 | /* | ||
57 | * generic definitions for IEEE 802.11 frames | ||
58 | */ | ||
59 | struct ieee80211_frame | ||
60 | { | ||
61 | u_int8_t i_fc[2]; | ||
62 | u_int8_t i_dur[2]; | ||
63 | u_int8_t i_addr1[IEEE80211_ADDR_LEN]; | ||
64 | u_int8_t i_addr2[IEEE80211_ADDR_LEN]; | ||
65 | u_int8_t i_addr3[IEEE80211_ADDR_LEN]; | ||
66 | u_int8_t i_seq[2]; | ||
67 | u_int8_t llc[4]; | ||
68 | #if DEBUG_wlan_ip_udp_packets_on_air > 1 | ||
69 | struct iph ip; | ||
70 | struct udphdr udp; | ||
71 | #endif | ||
72 | } GNUNET_PACKED; | ||
73 | |||
74 | /** | ||
75 | * function to fill the radiotap header | ||
76 | * @param plugin pointer to the plugin struct | ||
77 | * @param endpoint pointer to the endpoint | ||
78 | * @param header pointer to the radiotap header | ||
79 | * @return GNUNET_YES at success | ||
80 | */ | ||
81 | static int | ||
82 | getRadiotapHeader ( struct Radiotap_Send *header) | ||
83 | { | ||
84 | |||
85 | |||
86 | header->rate = 255; | ||
87 | header->tx_power = 0; | ||
88 | header->antenna = 0; | ||
89 | |||
90 | return GNUNET_YES; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * function to generate the wlan hardware header for one packet | ||
95 | * @param Header address to write the header to | ||
96 | * @param to_mac_addr address of the recipient | ||
97 | * @param plugin pointer to the plugin struct | ||
98 | * @param size size of the whole packet, needed to calculate the time to send the packet | ||
99 | * @return GNUNET_YES if there was no error | ||
100 | */ | ||
101 | static int | ||
102 | getWlanHeader (struct ieee80211_frame *Header, | ||
103 | const char *to_mac_addr, const char *mac, | ||
104 | unsigned int size) | ||
105 | { | ||
106 | uint16_t *tmp16; | ||
107 | const int rate = 11000000; | ||
108 | |||
109 | Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA; | ||
110 | Header->i_fc[1] = 0x00; | ||
111 | memcpy (&Header->i_addr3, &mac_bssid, sizeof (mac_bssid)); | ||
112 | memcpy (&Header->i_addr2, mac, | ||
113 | sizeof (mac_bssid)); | ||
114 | memcpy (&Header->i_addr1, to_mac_addr, sizeof (mac_bssid)); | ||
115 | |||
116 | tmp16 = (uint16_t *) Header->i_dur; | ||
117 | *tmp16 = (uint16_t) htole16 ((size * 1000000) / rate + 290); | ||
118 | Header->llc[0] = WLAN_LLC_DSAP_FIELD; | ||
119 | Header->llc[1] = WLAN_LLC_SSAP_FIELD; | ||
120 | |||
121 | #if DEBUG_wlan_ip_udp_packets_on_air > 1 | ||
122 | uint crc = 0; | ||
123 | uint16_t *x; | ||
124 | int count; | ||
125 | |||
126 | Header->ip.ip_dst.s_addr = *((uint32_t *) & to_mac_addr->mac[2]); | ||
127 | Header->ip.ip_src.s_addr = *((uint32_t *) & plugin->mac_address.mac[2]); | ||
128 | Header->ip.ip_v = 4; | ||
129 | Header->ip.ip_hl = 5; | ||
130 | Header->ip.ip_p = 17; | ||
131 | Header->ip.ip_ttl = 1; | ||
132 | Header->ip.ip_len = htons (size + 8); | ||
133 | Header->ip.ip_sum = 0; | ||
134 | x = (uint16_t *) & Header->ip; | ||
135 | count = sizeof (struct iph); | ||
136 | while (count > 1) | ||
137 | { | ||
138 | /* This is the inner loop */ | ||
139 | crc += (unsigned short) *x++; | ||
140 | count -= 2; | ||
141 | } | ||
142 | /* Add left-over byte, if any */ | ||
143 | if (count > 0) | ||
144 | crc += *(unsigned char *) x; | ||
145 | crc = (crc & 0xffff) + (crc >> 16); | ||
146 | Header->ip.ip_sum = htons (~(unsigned short) crc); | ||
147 | Header->udp.len = htons (size - sizeof (struct ieee80211_frame)); | ||
148 | |||
149 | #endif | ||
150 | |||
151 | return GNUNET_YES; | ||
152 | } | ||
153 | |||
154 | int main(int argc, char *argv[]){ | ||
155 | struct GNUNET_MessageHeader *msg; | ||
156 | struct GNUNET_MessageHeader *msg2; | ||
157 | struct ieee80211_frame *wlan_header; | ||
158 | struct Radiotap_Send *radiotap; | ||
159 | |||
160 | char inmac[6]; | ||
161 | char outmac[6]; | ||
162 | int pos; | ||
163 | long long count; | ||
164 | double bytes_per_s; | ||
165 | time_t start; | ||
166 | time_t akt; | ||
167 | |||
168 | if (4 != argc) { | ||
169 | fprintf( | ||
170 | stderr, | ||
171 | "This program must be started with the interface and the targets and source mac as argument.\nThis program was compiled at ----- %s ----\n", | ||
172 | __TIMESTAMP__); | ||
173 | fprintf(stderr, "Usage: interface-name mac-target mac-source\n" "\n"); | ||
174 | return 1; | ||
175 | } | ||
176 | |||
177 | |||
178 | pid_t pid; | ||
179 | int rv; | ||
180 | int commpipe[2]; /* This holds the fd for the input & output of the pipe */ | ||
181 | |||
182 | /* Setup communication pipeline first */ | ||
183 | if(pipe(commpipe)){ | ||
184 | fprintf(stderr,"Pipe error!\n"); | ||
185 | exit(1); | ||
186 | } | ||
187 | |||
188 | /* Attempt to fork and check for errors */ | ||
189 | if( (pid=fork()) == -1){ | ||
190 | fprintf(stderr,"Fork error. Exiting.\n"); /* something went wrong */ | ||
191 | exit(1); | ||
192 | } | ||
193 | |||
194 | if(pid){ | ||
195 | /* A positive (non-negative) PID indicates the parent process */ | ||
196 | //dup2(commpipe[1],1); /* Replace stdout with out side of the pipe */ | ||
197 | close(commpipe[0]); /* Close unused side of pipe (in side) */ | ||
198 | setvbuf(stdout,(char*)NULL,_IONBF,0); /* Set non-buffered output on stdout */ | ||
199 | |||
200 | sscanf(argv[3], "%x-%x-%x-%x-%x-%x", &inmac[0],&inmac[1],&inmac[2],&inmac[3],&inmac[4],&inmac[5]); | ||
201 | sscanf(argv[2], "%x-%x-%x-%x-%x-%x", &outmac[0],&outmac[1],&outmac[2],&outmac[3],&outmac[4],&outmac[5]); | ||
202 | |||
203 | msg = malloc(WLAN_MTU); | ||
204 | msg->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
205 | msg->size = htons (WLAN_MTU); | ||
206 | radiotap = (struct Radiotap_Send *) &msg[1]; | ||
207 | wlan_header = (struct ieee80211_frame *) &radiotap[1]; | ||
208 | pos = 0; | ||
209 | |||
210 | getRadiotapHeader(radiotap); | ||
211 | getWlanHeader(wlan_header, outmac, inmac, WLAN_MTU - sizeof(struct GNUNET_MessageHeader)); | ||
212 | |||
213 | start = time(NULL); | ||
214 | while (1){ | ||
215 | pos += write(commpipe[1], msg, WLAN_MTU - pos); | ||
216 | if (pos % WLAN_MTU == 0){ | ||
217 | pos = 0; | ||
218 | count ++; | ||
219 | |||
220 | if (count % 1000 == 0){ | ||
221 | akt = time(NULL); | ||
222 | bytes_per_s = count * WLAN_MTU / (akt - start); | ||
223 | bytes_per_s /= 1024; | ||
224 | printf("send %f kbytes/s\n", bytes_per_s); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | } | ||
229 | /* | ||
230 | sleep(2); | ||
231 | printf("Hello\n"); | ||
232 | sleep(2); | ||
233 | printf("Goodbye\n"); | ||
234 | sleep(2); | ||
235 | printf("exit\n"); | ||
236 | */ | ||
237 | //wait(&rv); /* Wait for child process to end */ | ||
238 | //fprintf(stderr,"Child exited with a %d value\n",rv); | ||
239 | } | ||
240 | else{ | ||
241 | /* A zero PID indicates that this is the child process */ | ||
242 | dup2(commpipe[0],0); /* Replace stdin with the in side of the pipe */ | ||
243 | close(commpipe[1]); /* Close unused side of pipe (out side) */ | ||
244 | /* Replace the child fork with a new process */ | ||
245 | if(execl("gnunet-transport-wlan-helper","gnunet-transport-wlan-helper", argv[1], NULL) == -1){ | ||
246 | fprintf(stderr,"execl Error!"); | ||
247 | exit(1); | ||
248 | } | ||
249 | } | ||
250 | return 0; | ||
251 | } | ||