/****************************************************************************** ** ** Game beacon advertiser ** ** Author: Gary Linscott (premandrake@hotmail.com) ** ** Copyright (c) 2004 Gary Linscott, All Rights Reserved (see license info below). ** ** Legal/Credits: ** ** HUGE thanks to crazyc for the checksum code! ** Heavily influenced by both the Airjack code and the Madwifi driver. ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned char __u8; typedef unsigned short __u16; typedef unsigned int __u32; #include "80211.h" struct llc_hdr { __u8 dsap; __u8 ssap; __u8 cntl; __u8 org_code[3]; __u16 type; } __attribute__ ((packed)); int initialize(char *device, int sd, int promisc) { struct ifreq ifr; strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(sd, SIOCGIFFLAGS, &ifr)<0) { perror("SIOCGIFFLAGS"); return -1; } if (promisc) ifr.ifr_flags |= IFF_PROMISC; else ifr.ifr_flags &= ~IFF_PROMISC; if(ioctl(sd, SIOCSIFFLAGS, &ifr)<0) { perror("SIOCSIFFLAGS"); return -1; } printf("Initialized device %s\n", device); if (ioctl(sd, SIOCGIFINDEX, &ifr)<0) { perror("SIOCGIFINDEX"); return -1; } return ifr.ifr_ifindex; } void shutdownDevices() { printf("User shutdown\n"); exit(0); } void printMAC(u_char *mac) { int i; printf("%.2x", mac[0]); for (i = 1; i < ETH_ALEN; i++) { printf(":%.2x", mac[i]); } } __u32 crc16(__u32 crc, __u32 data) { int j; crc ^= data; for (j = 0; j < 32; j++) { if (crc & 1) { crc = crc >> 1; crc ^= 0xA517; } else { crc = crc >> 1; } } return crc; } int main(int argc, char **argv) { // const u_char startMAC[8] = {0x00, 0x09, 0xBF, 0x0A, 0xF1, 0x86, 0, 0}; const u_char startMAC[8] = {0x00, 0x09, 0xBF, 0x0B, 0x79, 0xB0, 0, 0}; struct ethhdr *ethHeader; struct sockaddr_ll etherSocket; int sd; int ethIndex; u_char packet[65535]; u_char sendPacket[65535]; signal(SIGINT, shutdownDevices); signal(SIGQUIT, shutdownDevices); // Set up raw sockets for sending sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sd < 0) { printf("Couldn't create packet socket :(\n"); return 1; } if ((ethIndex = initialize("ath0", sd, 1)) < 0) { printf("Couldn't find adapter.\n"); return 1; } // Bind the socket to the interface memset(ðerSocket, 0, sizeof(etherSocket)); etherSocket.sll_family = AF_PACKET; etherSocket.sll_protocol = htons(ETH_P_ALL); etherSocket.sll_ifindex = ethIndex; if (bind(sd, (struct sockaddr *)ðerSocket, sizeof(etherSocket)) < 0) { printf("Couldn't bind socket.\n"); return 1; } FILE *file = fopen("simplemariobeacons", "rb"); int packetLength[10]; u_char packets[10][512]; int i; for (i = 0; i < 10; i++) { fread(&(packetLength[i]), 4, 1, file); memset(packets[i], 0, sizeof(packets[i])); fread(&(packets[i]), packetLength[i], 1, file); } // Packet description: // First 24 bytes, 802.11B header. 0x14 = packet sequence # (2 bytes?) // Next 12 bytes, fixed parameters, first 8 bytes, timestamp // 50 bytes in, beginning of custom tag. should be 0xDD (custom) // next byte, length of tag, 0x88 for mario beacon packets // From offset 52 from now on: // 0x00: 28 bytes - unknown (fixed for mario) // 0x1C: 1 byte - 0x02 on final packet, 0 otherwise // 0x1D: 2 bytes - unknown // 0x20: 1 byte - packet seq. number // 0x21: 2 bytes - CRC // 0x23: 1 byte - packet seq. number, but when 9, it's 1??? // 0x24: 1 byte - total number of packets in message // 0x25: 2 bytes - length of data segment? // 0x27: x bytes - packet data struct mbPacketHeader { __u8 unk1[28]; __u8 final; __u8 unk2[2]; __u8 seqNum; __u16 crc; __u8 seqNum2; __u8 numPackets; __u16 length; __u8 data[0x62]; } __attribute__ ((packed)); for (i=0; i<10; i++) { struct mbPacketHeader *ph = &(packets[i][52]); printf("final: %.2x, seqNum: %.2x, crc: %.4x, seqNum2: %.2x, num pkts: %.2x, length: %.4x --> ", ph->final, ph->seqNum, ph->crc, ph->seqNum2, ph->numPackets, ph->length); int j; __u32 crc = 0; for (j = 0x2B; j < 0x5E; j++) { crc += ((__u16*)packets[i])[j]; } __u16 *crcMem = (__u16*)&crc; crc = ((crcMem[0] + crcMem[1] + 1) * -1) & 0xffff; printf("Calced crc: %.4x - %s", crc, crc == ph->crc ? "GOOD!" : "bad"); printf("\n"); ph->crc = crc; } fclose(file); for (;;) { /* __u32 tmpcrc; for (tmpcrc=0xd000; tmpcrc<=0xffff; tmpcrc++) { if ((tmpcrc & 0xff) == 0) printf("%x\n",tmpcrc); struct mbPacketHeader *ph = &(packets[5][52]); ph->crc = tmpcrc;*/ for (i=0; i<10; i++) { memset(ðerSocket, 0, sizeof(etherSocket)); etherSocket.sll_family = AF_PACKET; etherSocket.sll_ifindex = ethIndex; memcpy(etherSocket.sll_addr, startMAC, 8); etherSocket.sll_halen = 6; if (sendto(sd, packets[i], packetLength[i], 0, (struct sockaddr *)ðerSocket, sizeof(etherSocket)) == -1) { printf("Error in sending packet.\n"); return 1; } struct timespec delay; delay.tv_sec = 0; delay.tv_nsec = 5000000; nanosleep(&delay, NULL); } // } } return 0; }