mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-08-01 23:19:33 +08:00
523 lines
16 KiB
C
523 lines
16 KiB
C
/* -*- Mode: C; tab-width: 4; -*- */
|
||
/*
|
||
* Copyright (C) 2009, HustMoon Studio
|
||
*
|
||
* 文件名称:myfunc.c
|
||
* 摘 要:认证相关算法及方法
|
||
* 作 者:HustMoon@BYHH
|
||
*/
|
||
#include "myfunc.h"
|
||
#include "md5.h"
|
||
#include "mycheck.h"
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <netinet/in.h>
|
||
#include <unistd.h>
|
||
#include <sys/socket.h>
|
||
#include <sys/ioctl.h>
|
||
#include <net/if.h>
|
||
#include <arpa/inet.h>
|
||
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
|
||
#include <net/if_dl.h>
|
||
#include <ifaddrs.h>
|
||
#endif
|
||
#include <sys/poll.h>
|
||
|
||
const u_char STANDARD_ADDR[] = {0x01,0x80,0xC2,0x00,0x00,0x03};
|
||
const u_char RUIJIE_ADDR[] = {0x01,0xD0,0xF8,0x00,0x00,0x03};
|
||
static const char *DATAFILE = "/etc/mentohust/"; /* 默认数据文件(目录) */
|
||
|
||
static int dataOffset; /* 抓包偏移 */
|
||
static u_int32_t echoKey = 0, echoNo = 0; /* Echo阶段所需 */
|
||
u_char *fillBuf = NULL; /* 填充包地址 */
|
||
int fillSize = 0; /* 填充包大小 */
|
||
int bufType = 0; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
|
||
u_char version[2]; /* 版本 */
|
||
#ifndef NO_ARP
|
||
u_int32_t rip = 0; /* 实际IP */
|
||
u_char gateMAC[6]; /* 网关MAC */
|
||
#endif
|
||
|
||
extern char password[];
|
||
extern char nic[];
|
||
extern char dataFile[];
|
||
extern u_int32_t ip, mask, gateway, dns, pingHost;
|
||
extern u_char localMAC[], destMAC[];
|
||
extern unsigned startMode, dhcpMode;
|
||
|
||
static int checkFile(); /* 检查数据文件 */
|
||
static int getVersion(); /* 获取8021x.exe版本号 */
|
||
static int getAddress(); /* 获取网络地址 */
|
||
static u_char encode(u_char base); /* 锐捷算法,颠倒一个字节的8位 */
|
||
static void checkSum(u_char *buf); /* 锐捷算法,计算两个字节的检验值 */
|
||
static int setProperty(u_char type, const u_char *value, int length); /* 设置指定属性 */
|
||
static int readPacket(int type); /* 读取数据 */
|
||
static int Check(const u_char *md5Seed); /* 校验算法 */
|
||
|
||
char *formatIP(u_int32_t ip)
|
||
{
|
||
static char tmp[16];
|
||
u_char *p = (u_char *)(&ip);
|
||
sprintf(tmp, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||
return tmp;
|
||
}
|
||
|
||
char *formatHex(const void *buf, int length)
|
||
{
|
||
static char hex[385];
|
||
u_char *p = (u_char *)buf;
|
||
int i;
|
||
if (length > 128)
|
||
length = 128;
|
||
for (i=0; i<length; i++)
|
||
sprintf(hex+3*i,"%02x:", p[i]);
|
||
hex[3*length-1] = '\0';
|
||
return hex;
|
||
}
|
||
|
||
static int checkFile() {
|
||
u_char Buf[16], *buf=Buf;
|
||
FILE *fp = NULL;
|
||
if ((fp=fopen(dataFile, "rb")) == NULL)
|
||
goto fileError;
|
||
if (fread(buf, 16, 1, fp)<1 || memcmp(buf, "HUST", 4)!=0) {
|
||
fclose(fp);
|
||
goto fileError;
|
||
}
|
||
dataOffset = (int)LTOBL(*(u_int32_t *)buf ^ *(u_int32_t *)(buf + 8)) + 16;
|
||
fseek(fp, 0, SEEK_END);
|
||
fillSize = ftell(fp);
|
||
fclose(fp);
|
||
if (dataOffset < 16)
|
||
goto fileError;
|
||
fillSize = (fillSize - dataOffset) / 2 + 0x17;
|
||
if (fillSize<0x80 || fillSize>0x397)
|
||
goto fileError;
|
||
return 0;
|
||
|
||
fileError:
|
||
if (dataFile[strlen(dataFile)-1] != '/')
|
||
printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
|
||
return -1;
|
||
}
|
||
|
||
static int getVersion() {
|
||
char file[0x100], *p;
|
||
DWORD ver;
|
||
strcpy(file, dataFile);
|
||
if ((p=strrchr(file, '/')+1) == (void *)1)
|
||
p = file;
|
||
strcpy(p, "8021x.exe");
|
||
if ((ver=getVer(file)) == (DWORD)-1)
|
||
return -1;
|
||
p = (char *)&ver;
|
||
version[0] = p[2];
|
||
version[1] = p[0];
|
||
bufType = 1;
|
||
return 0;
|
||
}
|
||
|
||
void newBuffer()
|
||
{
|
||
if (dataFile[0] == '\0')
|
||
strcpy(dataFile, DATAFILE);
|
||
getVersion();
|
||
if (checkFile() == 0)
|
||
bufType += 2;
|
||
else fillSize = (bufType==0 ? 0x80 : 0x1d7);
|
||
fillBuf = (u_char *)malloc(fillSize);
|
||
}
|
||
|
||
static int getAddress()
|
||
{
|
||
struct ifreq ifr;
|
||
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
|
||
struct ifaddrs *ifap, *p = NULL;
|
||
struct sockaddr_dl *sdl;
|
||
#endif
|
||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||
if (sock < 0)
|
||
{
|
||
printf("!! 创建套接字失败!\n");
|
||
return -1;
|
||
}
|
||
strcpy(ifr.ifr_name, nic);
|
||
|
||
#ifdef SIOCGIFHWADDR
|
||
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
|
||
goto getMACError;
|
||
memcpy(localMAC, ifr.ifr_hwaddr.sa_data, 6);
|
||
#else
|
||
if (getifaddrs(&ifap) == 0)
|
||
{
|
||
for (p=ifap; p; p=p->ifa_next)
|
||
{
|
||
if (p->ifa_name && strcmp(p->ifa_name, nic)==0)
|
||
{
|
||
sdl = (struct sockaddr_dl *)p->ifa_addr;
|
||
memcpy(localMAC, sdl->sdl_data + sdl->sdl_nlen, 6);
|
||
break;
|
||
}
|
||
}
|
||
freeifaddrs(ifap);
|
||
}
|
||
if (p == NULL)
|
||
goto getMACError;
|
||
#endif
|
||
|
||
if (startMode == 0)
|
||
memcpy(destMAC, STANDARD_ADDR, 6);
|
||
else if (startMode == 1)
|
||
memcpy(destMAC, RUIJIE_ADDR, 6);
|
||
|
||
#ifndef NO_ARP
|
||
gateMAC[0] = 0xFE;
|
||
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
|
||
printf("!! 在网卡%s上获取IP失败!\n", nic);
|
||
else {
|
||
rip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||
if (gateway!=0 && (startMode%3!=2 || ((u_char *)&gateway)[3]!=0x02))
|
||
gateMAC[0] = 0xFF;
|
||
}
|
||
if (dhcpMode!=0 || ip==-1)
|
||
ip = rip;
|
||
#else
|
||
if (dhcpMode!=0 || ip==-1) {
|
||
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
|
||
printf("!! 在网卡%s上获取IP失败!\n", nic);
|
||
else
|
||
ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||
}
|
||
#endif
|
||
|
||
if (dhcpMode!=0 || mask==-1) {
|
||
if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0)
|
||
printf("!! 在网卡%s上获取子网掩码失败!\n", nic);
|
||
else
|
||
mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||
}
|
||
close(sock);
|
||
|
||
printf("** 本机MAC:\t%s\n", formatHex(localMAC, 6));
|
||
printf("** 使用IP:\t%s\n", formatIP(ip));
|
||
printf("** 子网掩码:\t%s\n", formatIP(mask));
|
||
return 0;
|
||
|
||
getMACError:
|
||
close(sock);
|
||
printf("!! 在网卡%s上获取MAC失败!\n", nic);
|
||
return -1;
|
||
}
|
||
|
||
static u_char encode(u_char base) /* 算法,将一个字节的8位颠倒并取反 */
|
||
{
|
||
u_char result = 0;
|
||
int i;
|
||
for (i=0; i<8; i++)
|
||
{
|
||
result <<= 1;
|
||
result |= base&0x01;
|
||
base >>= 1;
|
||
}
|
||
return ~result;
|
||
}
|
||
|
||
static void checkSum(u_char *buf) /* 算法,计算两个字节的checksum */
|
||
{
|
||
u_char table[] =
|
||
{
|
||
0x00,0x00,0x21,0x10,0x42,0x20,0x63,0x30,0x84,0x40,0xA5,0x50,0xC6,0x60,0xE7,0x70,
|
||
0x08,0x81,0x29,0x91,0x4A,0xA1,0x6B,0xB1,0x8C,0xC1,0xAD,0xD1,0xCE,0xE1,0xEF,0xF1,
|
||
0x31,0x12,0x10,0x02,0x73,0x32,0x52,0x22,0xB5,0x52,0x94,0x42,0xF7,0x72,0xD6,0x62,
|
||
0x39,0x93,0x18,0x83,0x7B,0xB3,0x5A,0xA3,0xBD,0xD3,0x9C,0xC3,0xFF,0xF3,0xDE,0xE3,
|
||
0x62,0x24,0x43,0x34,0x20,0x04,0x01,0x14,0xE6,0x64,0xC7,0x74,0xA4,0x44,0x85,0x54,
|
||
0x6A,0xA5,0x4B,0xB5,0x28,0x85,0x09,0x95,0xEE,0xE5,0xCF,0xF5,0xAC,0xC5,0x8D,0xD5,
|
||
0x53,0x36,0x72,0x26,0x11,0x16,0x30,0x06,0xD7,0x76,0xF6,0x66,0x95,0x56,0xB4,0x46,
|
||
0x5B,0xB7,0x7A,0xA7,0x19,0x97,0x38,0x87,0xDF,0xF7,0xFE,0xE7,0x9D,0xD7,0xBC,0xC7,
|
||
0xC4,0x48,0xE5,0x58,0x86,0x68,0xA7,0x78,0x40,0x08,0x61,0x18,0x02,0x28,0x23,0x38,
|
||
0xCC,0xC9,0xED,0xD9,0x8E,0xE9,0xAF,0xF9,0x48,0x89,0x69,0x99,0x0A,0xA9,0x2B,0xB9,
|
||
0xF5,0x5A,0xD4,0x4A,0xB7,0x7A,0x96,0x6A,0x71,0x1A,0x50,0x0A,0x33,0x3A,0x12,0x2A,
|
||
0xFD,0xDB,0xDC,0xCB,0xBF,0xFB,0x9E,0xEB,0x79,0x9B,0x58,0x8B,0x3B,0xBB,0x1A,0xAB,
|
||
0xA6,0x6C,0x87,0x7C,0xE4,0x4C,0xC5,0x5C,0x22,0x2C,0x03,0x3C,0x60,0x0C,0x41,0x1C,
|
||
0xAE,0xED,0x8F,0xFD,0xEC,0xCD,0xCD,0xDD,0x2A,0xAD,0x0B,0xBD,0x68,0x8D,0x49,0x9D,
|
||
0x97,0x7E,0xB6,0x6E,0xD5,0x5E,0xF4,0x4E,0x13,0x3E,0x32,0x2E,0x51,0x1E,0x70,0x0E,
|
||
0x9F,0xFF,0xBE,0xEF,0xDD,0xDF,0xFC,0xCF,0x1B,0xBF,0x3A,0xAF,0x59,0x9F,0x78,0x8F,
|
||
0x88,0x91,0xA9,0x81,0xCA,0xB1,0xEB,0xA1,0x0C,0xD1,0x2D,0xC1,0x4E,0xF1,0x6F,0xE1,
|
||
0x80,0x10,0xA1,0x00,0xC2,0x30,0xE3,0x20,0x04,0x50,0x25,0x40,0x46,0x70,0x67,0x60,
|
||
0xB9,0x83,0x98,0x93,0xFB,0xA3,0xDA,0xB3,0x3D,0xC3,0x1C,0xD3,0x7F,0xE3,0x5E,0xF3,
|
||
0xB1,0x02,0x90,0x12,0xF3,0x22,0xD2,0x32,0x35,0x42,0x14,0x52,0x77,0x62,0x56,0x72,
|
||
0xEA,0xB5,0xCB,0xA5,0xA8,0x95,0x89,0x85,0x6E,0xF5,0x4F,0xE5,0x2C,0xD5,0x0D,0xC5,
|
||
0xE2,0x34,0xC3,0x24,0xA0,0x14,0x81,0x04,0x66,0x74,0x47,0x64,0x24,0x54,0x05,0x44,
|
||
0xDB,0xA7,0xFA,0xB7,0x99,0x87,0xB8,0x97,0x5F,0xE7,0x7E,0xF7,0x1D,0xC7,0x3C,0xD7,
|
||
0xD3,0x26,0xF2,0x36,0x91,0x06,0xB0,0x16,0x57,0x66,0x76,0x76,0x15,0x46,0x34,0x56,
|
||
0x4C,0xD9,0x6D,0xC9,0x0E,0xF9,0x2F,0xE9,0xC8,0x99,0xE9,0x89,0x8A,0xB9,0xAB,0xA9,
|
||
0x44,0x58,0x65,0x48,0x06,0x78,0x27,0x68,0xC0,0x18,0xE1,0x08,0x82,0x38,0xA3,0x28,
|
||
0x7D,0xCB,0x5C,0xDB,0x3F,0xEB,0x1E,0xFB,0xF9,0x8B,0xD8,0x9B,0xBB,0xAB,0x9A,0xBB,
|
||
0x75,0x4A,0x54,0x5A,0x37,0x6A,0x16,0x7A,0xF1,0x0A,0xD0,0x1A,0xB3,0x2A,0x92,0x3A,
|
||
0x2E,0xFD,0x0F,0xED,0x6C,0xDD,0x4D,0xCD,0xAA,0xBD,0x8B,0xAD,0xE8,0x9D,0xC9,0x8D,
|
||
0x26,0x7C,0x07,0x6C,0x64,0x5C,0x45,0x4C,0xA2,0x3C,0x83,0x2C,0xE0,0x1C,0xC1,0x0C,
|
||
0x1F,0xEF,0x3E,0xFF,0x5D,0xCF,0x7C,0xDF,0x9B,0xAF,0xBA,0xBF,0xD9,0x8F,0xF8,0x9F,
|
||
0x17,0x6E,0x36,0x7E,0x55,0x4E,0x74,0x5E,0x93,0x2E,0xB2,0x3E,0xD1,0x0E,0xF0,0x1E
|
||
};
|
||
u_char *checkSum = buf + 0x15;
|
||
int i, index;
|
||
for (i=0; i<0x15; i++)
|
||
{
|
||
index = checkSum[0] ^ buf[i];
|
||
checkSum[0] = checkSum[1] ^ table[index*2+1];
|
||
checkSum[1] = table[index*2];
|
||
}
|
||
for (i=0; i<0x17; i++)
|
||
buf[i] = encode(buf[i]);
|
||
}
|
||
|
||
int fillHeader()
|
||
{
|
||
if (getAddress() == -1)
|
||
return -1;
|
||
memset(fillBuf, 0, fillSize);
|
||
fillBuf[0x02] = 0x13;
|
||
fillBuf[0x03] = 0x11;
|
||
if (dhcpMode != 0)
|
||
fillBuf[0x04] = 0x01; /* DHCP位,使用1、不使用0 */
|
||
memcpy(fillBuf+0x05, &ip, 4);
|
||
memcpy(fillBuf+0x09, &mask, 4);
|
||
memcpy(fillBuf+0x0D, &gateway, 4);
|
||
memcpy(fillBuf+0x11, &dns, 4);
|
||
checkSum(fillBuf);
|
||
return 0;
|
||
}
|
||
|
||
static int setProperty(u_char type, const u_char *value, int length)
|
||
{
|
||
u_char *p = fillBuf+0x46, *end = fillBuf+fillSize-length-8; /* 形如1a 28 00 00 13 11 17 22,至少8个字节 */
|
||
while (p < end)
|
||
{
|
||
if (*p == 0x1a) /* 有些老版本没有前两个字节,包括xrgsu */
|
||
p += 2;
|
||
if (p[4] == type)
|
||
{
|
||
memcpy(p+4+p[5]-length, value, length);
|
||
return 0;
|
||
}
|
||
p += p[5] + 4;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
static int readPacket(int type)
|
||
{
|
||
u_char dhcp[] = {0x00};
|
||
FILE *fp = fopen(dataFile, "rb");
|
||
if (fp == NULL)
|
||
goto fileError;
|
||
type %= 2; /* 偶数读Start包,奇数读Md5包 */
|
||
fseek(fp, dataOffset+(fillSize-0x17)*type, SEEK_SET);
|
||
if (fread(fillBuf+0x17, fillSize-0x17, 1, fp) < 1) /* 前0x17字节是地址及校验值 */
|
||
{
|
||
fclose(fp);
|
||
goto fileError;
|
||
}
|
||
fclose(fp);
|
||
if (dhcpMode == 1) /* 二次认证第一次 */
|
||
dhcp[0] = 0x01;
|
||
setProperty(0x18, dhcp, 1);
|
||
setProperty(0x2D, localMAC, 6);
|
||
if (bufType == 3)
|
||
memcpy(fillBuf+0x3b, version, 2);
|
||
return 0;
|
||
|
||
fileError:
|
||
printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
|
||
bufType -= 2;
|
||
if (bufType==1 && fillSize<0x1d7) {
|
||
free(fillBuf);
|
||
fillSize = 0x1d7;
|
||
fillBuf = (u_char *)malloc(fillSize);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void fillStartPacket()
|
||
{
|
||
if (bufType <= 1) { /* 使用xrgsu? */
|
||
const u_char packet0[] = {
|
||
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0x11,0x00,0x28,0x1a,
|
||
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x91,0x66,0x64,0x93,0x67,0x60,0x65,0x62,0x62,
|
||
0x94,0x61,0x69,0x67,0x63,0x91,0x93,0x92,0x68,0x66,0x93,0x91,0x66,0x95,0x65,0xaa,
|
||
0xdc,0x64,0x98,0x96,0x6a,0x9d,0x66,0x00,0x00,0x13,0x11,0x18,0x06,0x02,0x00,0x00
|
||
};
|
||
const u_char packet1[] = {
|
||
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x04,0x0a,0x00,0x02,0x00,0x00,0x00,0x13,0x11,0x01,0x8c,0x1a,
|
||
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x36,0x38,0x44,0x43,0x31,0x32,0x33,0x42,0x37,
|
||
0x45,0x42,0x32,0x33,0x39,0x46,0x32,0x33,0x41,0x38,0x43,0x30,0x30,0x30,0x33,0x38,
|
||
0x38,0x34,0x39,0x38,0x36,0x33,0x39,0x1a,0x0c,0x00,0x00,0x13,0x11,0x18,0x06,0x00,
|
||
0x00,0x00,0x00,0x1a,0x0e,0x00,0x00,0x13,0x11,0x2d,0x08,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x1a,0x08,0x00,0x00,0x13,0x11,0x2f,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x35,
|
||
0x03,0x01,0x1a,0x18,0x00,0x00,0x13,0x11,0x36,0x12,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x18,0x00,0x00,0x13,0x11,
|
||
0x38,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x86,
|
||
0x13,0x4c,0x1a,0x88,0x00,0x00,0x13,0x11,0x4d,0x82,0x36,0x38,0x64,0x63,0x31,0x32,
|
||
0x33,0x62,0x30,0x37,0x65,0x62,0x32,0x33,0x39,0x66,0x32,0x33,0x61,0x38,0x30,0x64,
|
||
0x63,0x66,0x32,0x35,0x38,0x37,0x35,0x64,0x30,0x35,0x37,0x37,0x30,0x63,0x37,0x32,
|
||
0x31,0x65,0x34,0x35,0x36,0x34,0x35,0x65,0x35,0x33,0x37,0x61,0x62,0x33,0x35,0x31,
|
||
0x62,0x62,0x36,0x33,0x31,0x35,0x35,0x61,0x65,0x31,0x36,0x32,0x36,0x31,0x36,0x37,
|
||
0x65,0x62,0x30,0x39,0x32,0x32,0x33,0x65,0x32,0x61,0x30,0x61,0x37,0x38,0x30,0x33,
|
||
0x31,0x31,0x36,0x31,0x61,0x63,0x30,0x39,0x64,0x61,0x32,0x64,0x63,0x30,0x37,0x33,
|
||
0x36,0x39,0x33,0x61,0x34,0x66,0x35,0x61,0x32,0x39,0x32,0x38,0x36,0x37,0x35,0x31,
|
||
0x66,0x39,0x37,0x66,0x34,0x64,0x30,0x34,0x36,0x38,0x1a,0x28,0x00,0x00,0x13,0x11,
|
||
0x39,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x1a,0x48,0x00,0x00,0x13,0x11,0x54,0x42,0x48,0x55,0x53,0x54,0x4d,0x4f,
|
||
0x4f,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x08,0x00,0x00,0x13,0x11,
|
||
0x55,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x62,0x03,0x00,0x00,0x00,0x00,0x00,0x00
|
||
};
|
||
u_char dhcp[] = {0x00};
|
||
if (dhcpMode == 1) /* 二次认证第一次 */
|
||
dhcp[0] = 0x01;
|
||
if (bufType == 1) {
|
||
memcpy(fillBuf+0x17, packet1, sizeof(packet1));
|
||
memcpy(fillBuf+0x3b, version, 2);
|
||
} else
|
||
memcpy(fillBuf+0x17, packet0, sizeof(packet0));
|
||
setProperty(0x18, dhcp, 1);
|
||
setProperty(0x2D, localMAC, 6);
|
||
}
|
||
else if (readPacket(0) == -1) /* 读取数据失败就用默认的填充 */
|
||
fillStartPacket();
|
||
}
|
||
|
||
void fillMd5Packet(const u_char *md5Seed)
|
||
{
|
||
if (bufType <= 1) { /* 不使用数据包? */
|
||
/* xrgsu的Md5包与Start包只有一个字节的差异,若以其他版本为基础,可进一步区别对待 */
|
||
fillStartPacket();
|
||
if (bufType == 1)
|
||
Check(md5Seed);
|
||
} else {
|
||
if (readPacket(1) == -1)
|
||
fillMd5Packet(md5Seed);
|
||
else
|
||
Check(md5Seed);
|
||
}
|
||
echoNo = 0x0000102B; /* 初始化echoNo */
|
||
}
|
||
|
||
static int Check(const u_char *md5Seed) /* 客户端校验 */
|
||
{
|
||
char final_str[129];
|
||
int value;
|
||
printf("** 客户端版本:\t%d.%d\n", fillBuf[0x3B], fillBuf[0x3C]);
|
||
printf("** MD5种子:\t%s\n", formatHex(md5Seed, 16));
|
||
value = check_init(dataFile);
|
||
if (value == -1) {
|
||
printf("!! 缺少8021x.exe信息,客户端校验无法继续!\n");
|
||
return 1;
|
||
}
|
||
V2_check(md5Seed, final_str);
|
||
printf("** V2校验值:\t%s\n", final_str);
|
||
setProperty(0x17, (u_char *)final_str, 32);
|
||
check_free();
|
||
return 0;
|
||
}
|
||
|
||
void fillEchoPacket(u_char *echoBuf)
|
||
{
|
||
int i;
|
||
u_int32_t dd1=htonl(echoKey + echoNo), dd2=htonl(echoNo);
|
||
u_char *bt1=(u_char *)&dd1, *bt2=(u_char *)&dd2;
|
||
echoNo++;
|
||
for (i=0; i<4; i++)
|
||
{
|
||
echoBuf[0x18+i] = encode(bt1[i]);
|
||
echoBuf[0x22+i] = encode(bt2[i]);
|
||
}
|
||
}
|
||
|
||
void getEchoKey(const u_char *capBuf)
|
||
{
|
||
int i, offset = 0x1c+capBuf[0x1b]+0x69+24; /* 通过比较了大量抓包,通用的提取点就是这样的 */
|
||
u_char *base;
|
||
echoKey = ntohl(*(u_int32_t *)(capBuf+offset));
|
||
base = (u_char *)(&echoKey);
|
||
for (i=0; i<4; i++)
|
||
base[i] = encode(base[i]);
|
||
}
|
||
|
||
u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen)
|
||
{
|
||
u_char md5Src[80];
|
||
int md5Len = strlen(password);
|
||
md5Src[0] = id;
|
||
memcpy(md5Src+1, password, md5Len);
|
||
md5Len++;
|
||
if (startMode % 3 == 2) /* 赛尔? */
|
||
{
|
||
memcpy(md5Src+md5Len, "xxghlmxhzb", 10);
|
||
md5Len += 10;
|
||
}
|
||
memcpy(md5Src+md5Len, md5Seed, seedLen);
|
||
md5Len += seedLen;
|
||
return ComputeHash(md5Src, md5Len);
|
||
}
|
||
|
||
void fillCernetAddr(u_char *buf)
|
||
{
|
||
memcpy(buf+0x18, &ip, 4);
|
||
memcpy(buf+0x1C, &mask, 4);
|
||
memcpy(buf+0x20, &gateway, 4);
|
||
memset(buf+0x24, 0, 4); /* memcpy(buf+0x24, &dns, 4); */
|
||
}
|
||
|
||
int isOnline()
|
||
{
|
||
u_char echoPacket[] =
|
||
{
|
||
0x08,0x00,0x61,0xb2,0x02,0x00,0x01,0x00,0x57,0x65,0x6C,0x63,0x6F,0x6D,0x65,0x20,
|
||
0x74,0x6F,0x20,0x4D,0x65,0x6E,0x74,0x6F,0x48,0x55,0x53,0x54,0x21,0x0A,0x43,0x6F,
|
||
0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x39,
|
||
0x20,0x48,0x75,0x73,0x74,0x4D,0x6F,0x6F,0x6E,0x20,0x53,0x74,0x75,0x64,0x69,0x6F
|
||
};
|
||
int sock=-1, rtVal, t;
|
||
struct pollfd pfd;
|
||
struct sockaddr_in dest;
|
||
if (pingHost == 0)
|
||
return 0;
|
||
memset(&dest, 0, sizeof(dest));
|
||
dest.sin_family = AF_INET;
|
||
dest.sin_addr.s_addr = pingHost;
|
||
if ((sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||
goto pingError;
|
||
pfd.fd = sock;
|
||
pfd.events = POLLIN;
|
||
for (t=1; t<=3; t++) {
|
||
if (sendto(sock, echoPacket, sizeof(echoPacket), 0,
|
||
(struct sockaddr *)&dest, sizeof(dest)) < 0)
|
||
goto pingError;
|
||
rtVal = poll(&pfd, 1, t*1000);
|
||
if (rtVal == -1)
|
||
goto pingError;
|
||
if (rtVal > 0) {
|
||
close(sock);
|
||
return 0;
|
||
}
|
||
}
|
||
close(sock);
|
||
return -1;
|
||
|
||
pingError:
|
||
perror("!! Ping主机出错,关闭该功能");
|
||
if (sock != -1)
|
||
close(sock);
|
||
pingHost = 0;
|
||
return 0;
|
||
}
|