| 1 | /* |
|---|
| 2 | This file is part of lorcon |
|---|
| 3 | |
|---|
| 4 | lorcon is free software; you can redistribute it and/or modify |
|---|
| 5 | it under the terms of the GNU General Public License as published by |
|---|
| 6 | the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 | (at your option) any later version. |
|---|
| 8 | |
|---|
| 9 | lorcon is distributed in the hope that it will be useful, |
|---|
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | GNU General Public License for more details. |
|---|
| 13 | |
|---|
| 14 | You should have received a copy of the GNU General Public License |
|---|
| 15 | along with lorcon; if not, write to the Free Software |
|---|
| 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 17 | |
|---|
| 18 | Copyright (c) 2005 dragorn and Joshua Wright |
|---|
| 19 | */ |
|---|
| 20 | |
|---|
| 21 | #ifdef HAVE_CONFIG_H |
|---|
| 22 | #include "config.h" |
|---|
| 23 | #endif |
|---|
| 24 | |
|---|
| 25 | #ifdef HAVE_STDINT_H |
|---|
| 26 | #include <stdint.h> |
|---|
| 27 | #endif |
|---|
| 28 | #ifdef HAVE_INTTYPES_H |
|---|
| 29 | #include <inttypes.h> |
|---|
| 30 | #endif |
|---|
| 31 | |
|---|
| 32 | #include <string.h> |
|---|
| 33 | /* #include <netinet/in.h> */ |
|---|
| 34 | #include <stdlib.h> |
|---|
| 35 | #include <stdio.h> |
|---|
| 36 | #include "tx80211.h" |
|---|
| 37 | |
|---|
| 38 | #include "lorcon_packasm.h" |
|---|
| 39 | #include "lorcon_forge.h" |
|---|
| 40 | #include "ieee80211.h" |
|---|
| 41 | |
|---|
| 42 | uint8_t *ouilist[] = { |
|---|
| 43 | (uint8_t *) "\x00\x01\x03", (uint8_t *) "\x00\x01\x24", |
|---|
| 44 | (uint8_t *) "\x00\x02\x2D", (uint8_t *) "\x00\x02\x6F", |
|---|
| 45 | (uint8_t *) "\x00\x02\xA5", (uint8_t *) "\x00\x03\x2F", |
|---|
| 46 | (uint8_t *) "\x00\x04\x3A", (uint8_t *) "\x00\x04\x5A", |
|---|
| 47 | (uint8_t *) "\x00\x04\x75", (uint8_t *) "\x00\x04\xE2", |
|---|
| 48 | (uint8_t *) "\x00\x05\x5D", (uint8_t *) "\x00\x06\x25", |
|---|
| 49 | (uint8_t *) "\x00\x07\x0E", (uint8_t *) "\x00\x07\x50", |
|---|
| 50 | (uint8_t *) "\x00\x08\x21", (uint8_t *) "\x00\x09\x43", |
|---|
| 51 | (uint8_t *) "\x00\x09\x5B", (uint8_t *) "\x00\x09\x7C", |
|---|
| 52 | (uint8_t *) "\x00\x09\x92", (uint8_t *) "\x00\x09\xE8", |
|---|
| 53 | (uint8_t *) "\x00\x0A\x41", (uint8_t *) "\x00\x0A\x8A", |
|---|
| 54 | (uint8_t *) "\x00\x0C\x41", (uint8_t *) "\x00\x0D\x88", |
|---|
| 55 | (uint8_t *) "\x00\x30\x65", (uint8_t *) "\x00\x30\xAB", |
|---|
| 56 | (uint8_t *) "\x00\x30\xBD", (uint8_t *) "\x00\x40\x05", |
|---|
| 57 | (uint8_t *) "\x00\x40\x26", (uint8_t *) "\x00\x40\x96", |
|---|
| 58 | (uint8_t *) "\x00\x50\x08", (uint8_t *) "\x00\x50\x8B", |
|---|
| 59 | (uint8_t *) "\x00\x50\xDA", (uint8_t *) "\x00\x50\xF2", |
|---|
| 60 | (uint8_t *) "\x00\x60\x01", (uint8_t *) "\x00\x60\x1D", |
|---|
| 61 | (uint8_t *) "\x00\x60\x6D", (uint8_t *) "\x00\x60\xB3", |
|---|
| 62 | (uint8_t *) "\x00\x80\x37", (uint8_t *) "\x00\x80\xC6", |
|---|
| 63 | (uint8_t *) "\x00\x80\xC8", (uint8_t *) "\x00\x90\x4B", |
|---|
| 64 | (uint8_t *) "\x00\x90\xD1", (uint8_t *) "\x00\xA0\x04", |
|---|
| 65 | (uint8_t *) "\x00\xA0\xF8", (uint8_t *) "\x00\xE0\x29", |
|---|
| 66 | (uint8_t *) "\x08\x00\x46", NULL |
|---|
| 67 | }; |
|---|
| 68 | |
|---|
| 69 | void lcpf_randmac(uint8_t *addr, int valid) { |
|---|
| 70 | static int listlen = 0; |
|---|
| 71 | |
|---|
| 72 | if (listlen == 0) { |
|---|
| 73 | while (ouilist[listlen] != NULL) { |
|---|
| 74 | listlen++; |
|---|
| 75 | }; |
|---|
| 76 | } |
|---|
| 77 | |
|---|
| 78 | if (valid) { |
|---|
| 79 | memcpy(addr, ouilist[rand() % listlen], 3); |
|---|
| 80 | } else { |
|---|
| 81 | addr[0] = rand() % 255; |
|---|
| 82 | addr[1] = rand() % 255; |
|---|
| 83 | addr[2] = rand() % 255; |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | addr[3] = rand() % 255; |
|---|
| 87 | addr[4] = rand() % 255; |
|---|
| 88 | addr[5] = rand() % 255; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | void lcpf_qosheaders(struct lcpa_metapack *pack, unsigned int priority, |
|---|
| 92 | unsigned int eosp, unsigned int ackpol) { |
|---|
| 93 | uint8_t chunk[2]; |
|---|
| 94 | |
|---|
| 95 | /* Bits 0 and 4 are reserved. */ |
|---|
| 96 | chunk[0] = 0; |
|---|
| 97 | chunk[0] = ((priority << 5) | (eosp << 3) | (ackpol << 1)); |
|---|
| 98 | /* All 8 bits reserved */ |
|---|
| 99 | chunk[1] = 0; |
|---|
| 100 | pack = lcpa_append_copy(pack, "80211QOSHDR", 2, chunk); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | void lcpf_80211ctrlheaders(struct lcpa_metapack *pack, |
|---|
| 104 | unsigned int type, unsigned int subtype, unsigned int fcflags, |
|---|
| 105 | unsigned int duration, uint8_t *mac1) |
|---|
| 106 | { |
|---|
| 107 | |
|---|
| 108 | /* Re-use a single buffer and use the copy ops, saves a malloc |
|---|
| 109 | * thrash */ |
|---|
| 110 | uint8_t chunk[2]; |
|---|
| 111 | uint16_t *sixptr; |
|---|
| 112 | |
|---|
| 113 | chunk[0] = ((type << 2) | (subtype << 4)); |
|---|
| 114 | chunk[1] = (uint8_t) fcflags; |
|---|
| 115 | pack = lcpa_append_copy(pack, "80211FC", 2, chunk); |
|---|
| 116 | |
|---|
| 117 | sixptr = (uint16_t *) chunk; |
|---|
| 118 | *sixptr = tx80211_hton16((uint16_t) duration); |
|---|
| 119 | pack = lcpa_append_copy(pack, "80211DUR", 2, chunk); |
|---|
| 120 | |
|---|
| 121 | if (mac1 != NULL) { |
|---|
| 122 | pack = lcpa_append_copy(pack, "80211MAC1", 6, mac1); |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | return; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | void lcpf_data(struct lcpa_metapack *pack, unsigned int fcflags, |
|---|
| 129 | unsigned int duration, uint8_t *mac1, uint8_t *mac2, |
|---|
| 130 | uint8_t *mac3, uint8_t *mac4, unsigned int fragment, |
|---|
| 131 | unsigned int sequence) { |
|---|
| 132 | |
|---|
| 133 | lcpf_80211headers(pack, WLAN_FC_TYPE_DATA, WLAN_FC_SUBTYPE_DATA, |
|---|
| 134 | fcflags, duration, mac1, mac2, mac3, mac4, fragment, sequence); |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | void lcpf_80211headers(struct lcpa_metapack *pack, unsigned int type, |
|---|
| 138 | unsigned int subtype, unsigned int fcflags, |
|---|
| 139 | unsigned int duration, |
|---|
| 140 | uint8_t *mac1, uint8_t *mac2, uint8_t *mac3, |
|---|
| 141 | uint8_t *mac4, unsigned int fragment, |
|---|
| 142 | unsigned int sequence) { |
|---|
| 143 | |
|---|
| 144 | /* Re-use a single buffer and use the copy ops, saves a malloc |
|---|
| 145 | * thrash */ |
|---|
| 146 | uint8_t chunk[2]; |
|---|
| 147 | uint16_t *sixptr; |
|---|
| 148 | |
|---|
| 149 | chunk[0] = ((type << 2) | (subtype << 4)); |
|---|
| 150 | chunk[1] = (uint8_t) fcflags; |
|---|
| 151 | pack = lcpa_append_copy(pack, "80211FC", 2, chunk); |
|---|
| 152 | |
|---|
| 153 | sixptr = (uint16_t *) chunk; |
|---|
| 154 | *sixptr = tx80211_hton16((uint16_t) duration); |
|---|
| 155 | pack = lcpa_append_copy(pack, "80211DUR", 2, chunk); |
|---|
| 156 | |
|---|
| 157 | if (mac1 != NULL) |
|---|
| 158 | pack = lcpa_append_copy(pack, "80211MAC1", 6, mac1); |
|---|
| 159 | if (mac2 != NULL) |
|---|
| 160 | pack = lcpa_append_copy(pack, "80211MAC2", 6, mac2); |
|---|
| 161 | if (mac3 != NULL) |
|---|
| 162 | pack = lcpa_append_copy(pack, "80211MAC3", 6, mac3); |
|---|
| 163 | if (mac4 != NULL) |
|---|
| 164 | pack = lcpa_append_copy(pack, "80211MAC4", 6, mac4); |
|---|
| 165 | |
|---|
| 166 | *sixptr = ((sequence << 4) | fragment); |
|---|
| 167 | pack = lcpa_append_copy(pack, "80211FRAGSEQ", 2, chunk); |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | void lcpf_beacon(struct lcpa_metapack *pack, uint8_t *src, uint8_t *bssid, |
|---|
| 171 | int framecontrol, int duration, int fragment, int sequence, |
|---|
| 172 | uint64_t timestamp, int beacon, int capabilities) { |
|---|
| 173 | uint8_t chunk[8]; |
|---|
| 174 | uint16_t *sixptr = (uint16_t *) chunk; |
|---|
| 175 | uint64_t *ch64 = (uint64_t *) chunk; |
|---|
| 176 | |
|---|
| 177 | memcpy(chunk, "\xFF\xFF\xFF\xFF\xFF\xFF", 6); |
|---|
| 178 | lcpf_80211headers(pack, 0, 8, framecontrol, duration, |
|---|
| 179 | chunk, src, bssid, NULL, |
|---|
| 180 | fragment, sequence); |
|---|
| 181 | |
|---|
| 182 | *ch64 = timestamp; |
|---|
| 183 | pack = lcpa_append_copy(pack, "BEACONBSSTIME", 8, chunk); |
|---|
| 184 | |
|---|
| 185 | *sixptr = beacon; |
|---|
| 186 | pack = lcpa_append_copy(pack, "BEACONINT", 2, chunk); |
|---|
| 187 | |
|---|
| 188 | *sixptr = capabilities; |
|---|
| 189 | pack = lcpa_append_copy(pack, "BEACONCAP", 2, chunk); |
|---|
| 190 | |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | void lcpf_add_ie(struct lcpa_metapack *pack, uint8_t num, uint8_t len, uint8_t *data) { |
|---|
| 194 | uint8_t chunk[257]; |
|---|
| 195 | |
|---|
| 196 | chunk[0] = num; |
|---|
| 197 | chunk[1] = len; |
|---|
| 198 | memcpy(&(chunk[2]), data, len); |
|---|
| 199 | |
|---|
| 200 | lcpa_append_copy(pack, "IETAG", len + 2, chunk); |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | void lcpf_deauth(struct lcpa_metapack *pack, uint8_t *src, uint8_t *dst, |
|---|
| 204 | uint8_t *bssid, int framecontrol, |
|---|
| 205 | int duration, int fragment, |
|---|
| 206 | int sequence, int reasoncode) { |
|---|
| 207 | uint8_t chunk[2]; |
|---|
| 208 | uint16_t *ch16 = (uint16_t *) chunk; |
|---|
| 209 | |
|---|
| 210 | lcpf_80211headers(pack, 0, 12, framecontrol, duration, |
|---|
| 211 | dst, src, bssid, NULL, fragment, sequence); |
|---|
| 212 | |
|---|
| 213 | *ch16 = reasoncode; |
|---|
| 214 | lcpa_append_copy(pack, "REASONCODE", 2, chunk); |
|---|
| 215 | } |
|---|
| 216 | |
|---|
| 217 | void lcpf_disassoc(struct lcpa_metapack *pack, uint8_t *src, uint8_t *dst, |
|---|
| 218 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 219 | int sequence, int reasoncode) { |
|---|
| 220 | uint8_t chunk[2]; |
|---|
| 221 | uint16_t *ch16 = (uint16_t *) chunk; |
|---|
| 222 | |
|---|
| 223 | lcpf_80211headers(pack, 0, 10, framecontrol, duration, |
|---|
| 224 | dst, src, bssid, NULL, fragment, sequence); |
|---|
| 225 | |
|---|
| 226 | *ch16 = reasoncode; |
|---|
| 227 | lcpa_append_copy(pack, "REASONCODE", 2, chunk); |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | void lcpf_probereq(struct lcpa_metapack *pack, uint8_t *src, int framecontrol, |
|---|
| 231 | int duration, int fragment, int sequence) { |
|---|
| 232 | |
|---|
| 233 | uint8_t chunk[6] = "\xFF\xFF\xFF\xFF\xFF\xFF"; |
|---|
| 234 | lcpf_80211headers(pack, 0, 4, framecontrol, duration, |
|---|
| 235 | chunk, src, chunk, NULL, fragment, sequence); |
|---|
| 236 | } |
|---|
| 237 | |
|---|
| 238 | void lcpf_proberesp(struct lcpa_metapack *pack, uint8_t *dst, uint8_t *src, |
|---|
| 239 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 240 | int sequence, uint64_t timestamp, int beaconint, |
|---|
| 241 | int capabilities) |
|---|
| 242 | { |
|---|
| 243 | uint8_t chunk[8]; |
|---|
| 244 | uint16_t *sixptr = (uint16_t *) chunk; |
|---|
| 245 | uint64_t *ch64 = (uint64_t *) chunk; |
|---|
| 246 | |
|---|
| 247 | lcpf_80211headers(pack, 0, 5, framecontrol, duration, |
|---|
| 248 | dst, src, bssid, NULL, |
|---|
| 249 | fragment, sequence); |
|---|
| 250 | |
|---|
| 251 | *ch64 = timestamp; |
|---|
| 252 | pack = lcpa_append_copy(pack, "BEACONBSSTIME", 8, chunk); |
|---|
| 253 | |
|---|
| 254 | *sixptr = beaconint; |
|---|
| 255 | pack = lcpa_append_copy(pack, "BEACONINT", 2, chunk); |
|---|
| 256 | |
|---|
| 257 | *sixptr = capabilities; |
|---|
| 258 | pack = lcpa_append_copy(pack, "BEACONCAP", 2, chunk); |
|---|
| 259 | |
|---|
| 260 | } |
|---|
| 261 | |
|---|
| 262 | void lcpf_rts(struct lcpa_metapack *pack, uint8_t *recvmac, uint8_t *transmac, |
|---|
| 263 | int framecontrol, int duration) |
|---|
| 264 | { |
|---|
| 265 | lcpf_80211ctrlheaders(pack, 1, 11, framecontrol, duration, recvmac); |
|---|
| 266 | pack = lcpa_append_copy(pack, "TRANSMITTERMAC", 6, transmac); |
|---|
| 267 | } |
|---|
| 268 | |
|---|
| 269 | void lcpf_authreq(struct lcpa_metapack *pack, uint8_t *dst, uint8_t *src, |
|---|
| 270 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 271 | int sequence, uint16_t authalgo, uint16_t auth_seq, |
|---|
| 272 | uint16_t auth_status) |
|---|
| 273 | { |
|---|
| 274 | uint8_t chunk[2]; |
|---|
| 275 | uint16_t *sixptr = (uint16_t *) chunk; |
|---|
| 276 | |
|---|
| 277 | lcpf_80211headers(pack, 0, 11, framecontrol, duration, |
|---|
| 278 | dst, src, bssid, NULL, |
|---|
| 279 | fragment, sequence); |
|---|
| 280 | |
|---|
| 281 | *sixptr = authalgo; |
|---|
| 282 | pack = lcpa_append_copy(pack, "AUTHALGO", 2, chunk); |
|---|
| 283 | *sixptr = auth_seq; |
|---|
| 284 | pack = lcpa_append_copy(pack, "AUTHSEQ", 2, chunk); |
|---|
| 285 | *sixptr = auth_status; |
|---|
| 286 | pack = lcpa_append_copy(pack, "AUTHSTATUS", 2, chunk); |
|---|
| 287 | |
|---|
| 288 | } |
|---|
| 289 | |
|---|
| 290 | /* Authentication response is the same for open networks, with IE tags */ |
|---|
| 291 | void lcpf_authresq(struct lcpa_metapack *pack, uint8_t *dst, uint8_t *src, |
|---|
| 292 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 293 | int sequence, uint16_t authalgo, uint16_t auth_seq, |
|---|
| 294 | uint16_t auth_status) |
|---|
| 295 | { |
|---|
| 296 | lcpf_authreq(pack, dst, src, bssid, framecontrol, duration, fragment, |
|---|
| 297 | sequence, authalgo, auth_seq, auth_status); |
|---|
| 298 | } |
|---|
| 299 | |
|---|
| 300 | void lcpf_assocreq(struct lcpa_metapack *pack, uint8_t *dst, uint8_t *src, |
|---|
| 301 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 302 | int sequence, uint16_t capabilities, uint16_t listenint) |
|---|
| 303 | { |
|---|
| 304 | uint8_t chunk[2]; |
|---|
| 305 | uint16_t *sixptr = (uint16_t *) chunk; |
|---|
| 306 | |
|---|
| 307 | lcpf_80211headers(pack, 0, 5, framecontrol, duration, |
|---|
| 308 | dst, src, bssid, NULL, |
|---|
| 309 | fragment, sequence); |
|---|
| 310 | |
|---|
| 311 | *sixptr = capabilities; |
|---|
| 312 | pack = lcpa_append_copy(pack, "ASSOCREQCAPAB", 2, chunk); |
|---|
| 313 | *sixptr = listenint; |
|---|
| 314 | pack = lcpa_append_copy(pack, "ASSOCREQLI", 2, chunk); |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | void lcpf_assocresp(struct lcpa_metapack *pack, uint8_t *dst, uint8_t *src, |
|---|
| 318 | uint8_t *bssid, int framecontrol, int duration, int fragment, |
|---|
| 319 | int sequence, uint16_t capabilities, uint16_t status, |
|---|
| 320 | uint16_t aid) |
|---|
| 321 | { |
|---|
| 322 | uint8_t chunk[2]; |
|---|
| 323 | uint16_t *sixptr = (uint16_t *) chunk; |
|---|
| 324 | |
|---|
| 325 | lcpf_80211headers(pack, 0, 5, framecontrol, duration, |
|---|
| 326 | dst, src, bssid, NULL, |
|---|
| 327 | fragment, sequence); |
|---|
| 328 | |
|---|
| 329 | *sixptr = capabilities; |
|---|
| 330 | pack = lcpa_append_copy(pack, "ASSOCRESPCAPAB", 2, chunk); |
|---|
| 331 | *sixptr = status; |
|---|
| 332 | pack = lcpa_append_copy(pack, "ASSOCRESPSTAT", 2, chunk); |
|---|
| 333 | *sixptr = aid; |
|---|
| 334 | pack = lcpa_append_copy(pack, "ASSOCRESPID", 2, chunk); |
|---|
| 335 | } |
|---|