使用方法

最近更新时间:2019-05-15 10:55:58

通用版本

数据结构和函数说明

  • class ToaFetcher
    主体类,用于管理 TOA 的获取和释放。
  • InitUpToaFetcher
    1. 函数说明
      该函数用于初始化 TOA fetcher。
      bool InitUpToaFetcher(char *ncard_ip_str, char *svr_ip_str, u_short svr_port[], u_short svr_port_num, u_short cache_secs=TIMER_CACHE_SECS)
    2. 入参说明
      • ncard_ip_str: 用于识别网络接口的 IP 地址字符串,例如:10.75.132.39,该网卡为与客户端通信的网卡,如下图所示:
      • svr_ip_str:服务器的 IP 地址字符串,例如:10.75.132.39,用于过滤 TCP 流。
      • svr_port:服务器的端口列表,用于过滤 TCP 流,最多可以填三个端口,svr_port 和 port_range_ptr 至少设置其中一个。
      • svr_port_num:服务器的端口个数。
      • port_range_ptr:服务器的端口范围数组指针,其中元素为指向一个字符串的指针,端口范围字符串格式:10001-10005,用于过滤 TCP 流,最多填三个范围,svr_port 和 port_range_ptr 至少设置其中一个。
      • port_range_num:服务器的端口范围个数。
      • cache_secs:缓存的时长,单位:秒,默认15秒,详见 toa_fetcher.h:TIMER_CACHE_SECS,缓存时间到期后,将不再保存该 TOA。
    3. 返回值
      • TRUE:表示创建 TOA 获取旁路线程成功。
      • FALSE:表示创建 TOA 获取旁路线程失败。
  • FetchToaValue
    1. 函数说明
      该函数用于获取 TOA 值,tcp-syn 包交互后,最长需要等待1ms后可以获取到 TOA,正常情况下三次握手需要消耗1ms以上。
      bool FetchToaValue(u_long fake_client_ip_addr, u_short fake_client_port, u_long &real_client_ip_addr, u_short &real_client_port)
    2. 入参说明
      • fake_client_ip_addr:客户端伪 IP 地址,采用网络序存储,从服务器 accept 函数返回的对端地址中获取。
      • fake_client_port:客户端伪端口号,采用网络序存储,从服务器 accept 函数返回的对端地址中获取。
      • real_client_ip_addr:客户端真实 IP 地址,采用网络序存储,从 TOA 中获取。
      • real_client_port:客户端真实端口号,采用网络序存储,从 TOA 中获取。
    3. 返回值
      • TRUE:获取 TOA 成功。
      • FALSE:未获取到 TOA,一般是超过缓存时间导致 TOA 被清掉。
  • StopToaFetcher
    1. 函数说明
      该函数用于停止 TOA fetcher。
      void StopToaFetcher()
    2. 入参说明
      无。
    3. 返回值
      无。
  • GetFetcherStatus
    1. 函数说明
      该函数用于获取 Fetcher 状态。
      int GetFetcherStatus()
    2. 入参说明
      无。
    3. 返回值
      • 0:表示初始状态。创建实例后,初始状态处于该状态,Fetcher 初始化中,该状态保持不变,当中间出现错误时,返回 -1,当成功运行时,返回 1。
      • -1:表示异常状态。
      • 1:表示正常运行中。
  • FetchThreadHandler
    1. 函数说明
      该函数用于获取 TOA 旁路线程句柄。
      HANDLE FetchThreadHandler()
    2. 入参说明
      无。
    3. 返回值
      TOA 旁路线程句柄,当 ToaFetcher 实例被销毁时,将主动关闭该句柄。
  • FetchErrorInfo
    1. 函数说明
      该函数用于获取错误码。
      bool FetchErrorInfo(int* err_code_ptr, char* err_msg_ptr)
    2. 入参说明
      • err_code_ptr:一个整型指针指向错误码,用于返回错误码。
      • err_msg_ptr :一个字符指针指向字符串缓冲区,至少50字节,用于返回错误信息。
    3. 返回值
      • TRUE:获取正常。
      • FALSE:获取异常。

错误码

错误码 错误信息 说明
0 Ok 正常
-1001 Exceed max server port number 超过最大的端口数,请检查 InitUpToaFetcher:svr_port_num。
-1002 Invalid IP address 非法的 IPv4 地址。
-1003 No suitable network interface 未找到合适的网络接口。
-1004 System Error: find dev error 系统错误:未找到 dev,请联系 lib 开发者。
-1005 System Error: start timer error 系统错误:定时器启动错误,请联系 lib 开发者。
-1006 System Error: compile filter error 系统错误:过滤规则编译错误,请联系lib开发者。
-1007 System Error: set filter error 系统错误:过滤规则设置错误,请联系 lib 开发者。
-1008 System Error: open pcap error 系统错误:打开 dev 错误,请联系 lib 开发者。
-1009 System Error: start pcap error 系统错误:启动监听错误,请联系 lib 开发者。
-1010 System Error: begin thread error 系统错误:启动线程错误,请联系 lib 开发者。
-1999 Unknown error 未知错误,请联系 lib 开发者。

示例

  • 初始化 ToaFetcher:
    char ncard_ip_str[] = "1.1.1.1";
    char svr_ip_str[] = "1.1.1.1";
    char port_range[3][100] = {"10001-10005", "20001-20005", "30001-30005"};
    char* port_range_ptr[3] = {port_range[0], port_range[1], port_range[2]};
          u_short svr_port_list[3] = {1111, 2222, 3333};
          ToaFetcher inst = ToaFetcher();
          inst.InitUpToaFetcher((char*)ncard_ip_str, (char*)svr_ip_str, svr_port_list, 3);
  • 获取 TOA:
    void GetToa(SOCKADDR_IN client_addr, ToaFetcher * toa_fetcher_ptr)
    {
      u_long fake_client_ip_addr = 0;
      u_short fake_client_port = 0;
      u_long real_client_ip_addr = 0;
      u_short real_client_port = 0;
      memcpy(&fake_client_ip_addr, &client_addr.sin_addr, 4);
      memcpy(&fake_client_port, &client_addr.sin_port, 2);
      bool ret = toa_fetcher_ptr->FetchToaValue(fake_client_ip_addr, fake_client_port, real_client_ip_addr, real_client_port);
      if(ret == FALSE){
          printf("No toa found\n");
      }else{
          //fpp: 自定义的打印函数
          fpp("real_client_ip_addr", &real_client_ip_addr, 4);    
      fpp("real_client_port", &real_client_port, 2);
      }
    }

Go版本

TOA 获取端通过本机 UDP 通信的方式向 toa_win.exe 获取真实 IP 地址。

协议格式

  • 请求:| ID(4Bytes)| FakeIPAddress(4Bytes)| FakePort(2Bytes)|
    字段说明如下:

    • ID:4字节,用于唯一标识一个请求,响应中将原始返回。
    • FakeIPAddrss:4字节,客户端伪 IP 地址,采用网络序存储,从服务器 accept 函数返回的对端地址中获取。
    • FakePort:2字节,客户端伪端口号,采用网络序存储,从服务器 accept 函数返回的对端地址中获取。
  • 响应:| ID(4Bytes)| Code(1Byte)| RealIPAddress(4Bytes)| RealPort(2Bytes)|
    字段说明如下:

    • ID:4字节,用于唯一标识一个请求,和请求携带上来的一致。
    • Code:1字节,0:成功获取到真实 IP 和 Port,1:获取失败。
    • RealIPAddress:4字节,网络序,当 Code=0 时存在,表示真实的客户端 IP 地址。
    • RealPort:2字节,网络序,当 Code=0 时存在,表示真实的客户端 Port。

示例

详情请参见 demo.go,可以自行开发 TOA 获取客户端程序,也可以使用 demo.go 中的 queryToa 函数进行获取。

  1. 函数说明
    func queryToa(serverAddr string, fakeIp string, fakePort uint16)(int32, string, uint16)
  2. 入参说明
    • serverAddr:字符串类型,toa_win.exe 的服务通信地址,格式:127.0.0.1:9999。
    • fakeIp:字符串类型,伪 IP 地址,格式:1.2.3.4。
    • fakePort:uint16类型,伪 Port,格式:8899。
  3. 返回值
    • 第一个返回值:int32类型,用于表示 error code。
      • 0:成功获取
      • -1:toa 获取失败,可能因为 fakeIP 和 fakePort 不对或者 cache 到期。
      • -2:网络通信导致的失败。
    • 第二个返回值:字符串类型,当 toa 获取成功时,返回真实的 IP,否则为空字符串。
    • 第三个返回值: uint16 类型,当 toa 获取成功时,返回真实的 Port,否则为0。