Ipfilter.cpp
上传用户:heseme
上传日期:2009-12-23
资源大小:228k
文件大小:73k
开发平台:

Visual C++

  1. //对日志和流量统计都将有所改变
  2. //IP源路由
  3. //注意:类表仅仅用于对内网主机的设置
  4. //内网访问的是允许表
  5. //注意:覆盖表是当内网到外网时使用的对外部主机ip地址的设置(仅当tcp使用)
  6. #include "StdAfx.h"
  7. #include "ip.h"
  8. #include "ipfilter.h"
  9. #include "winsock2.h"
  10. #include "Struct.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. extern DefaultSetData TheDefaultSetData;
  17. struct LogView  logview;
  18. struct LogViewIcmp  logviewIcmp;
  19. extern USHORT logType;
  20.  Statistics filterstats = { NO };  //缺省运行状态
  21.  FilterConfig filtercfg = { DEFAULT_SYSL_MASK }; //缺省日志掩码
  22.  ULONG ptrs_initialized = 0;      
  23.  ULONG initialized = NO;
  24. extern HWND myhWnd1;
  25.  pointerStruct active, newspace;
  26.  FILE *hlogFile,*statFile;
  27.  int filtercount=0;
  28.  struct pkt_struct *mtodPkt(BYTE *r);
  29.  static void freeOutTree (OutaddrTreeNode *tbl, unsigned char level);
  30.  VOID GetStatisticsInfo(Statistics* StatisticInfo);
  31.  USHORT treeOutLookup (OutaddrTreeNode *tbl, ULONG addr, unsigned short max_group);
  32.  static void 
  33.  syslogMessage(unsigned char eventNo,ULONG protocolNo=NULL,ULONG srcAddr=NULL,
  34.   ULONG dstAddr=NULL, unsigned short srcPort=NULL,unsigned short dstPort=NULL,
  35.   unsigned char icmptype=NULL,UCHAR dostype=NULL);
  36.  void writestatistic();
  37.  VOID clearipfilter();
  38.  //释放主结构空间
  39.  static void freeAllPointers (pointerStruct *p);
  40. //初始化主结构,将groups设置为1(1各主机类)
  41.  static ULONG  initTables (pointerStruct *p, unsigned short groups);
  42. //释放地址树空间(pointerStruct中的指针)
  43.  static void freeTree (addrTreeNode *tbl, unsigned char level);
  44. //现在使用的函数
  45. static ULONG
  46. OutnetaddToTree(OutaddrTreeNode *tbl, in_addr_t addr,/*主机类起始地址,*/ 
  47. unsigned short hostnums,/*从主机类起始地址开始的主机数,*/
  48. unsigned short group/*组号与端口列表的组号一至*/);
  49. static ULONG
  50. GjaddToTree(addrTreeNode *tbl, in_addr_t addr/*主机类起始地址*/, 
  51. unsigned short hostnums/*从主机类起始地址开始的主机数*/,
  52. unsigned short group/*组号与端口列表的组号一至*/);
  53. //将portListReq结构中的端口列表添加到(pointerStruct的)PortListEntry结构中
  54. static ULONG copyGroup (portListReq *u, PortListEntry *kptr);
  55. //设置端口列表请求到主结构中
  56. static ULONG portListRequest (portListReq *u, pointerStruct *p);
  57. //添加地址表请求
  58. static ULONG addrTreeRequest (addrTreeReq *u);
  59. //添加拒绝表请求(到主结构)
  60. static ULONG rejaccTableRequest (ULONG id, rejaccTableReq *u, pointerStruct *p);
  61. static int
  62. OutrejaccTableRequest(int id, rejaccTableReq *u, pointerStruct *p);
  63. //添加覆盖表请求
  64. static ULONG overrideTableRequest (overrideTableReq *u, pointerStruct *p);
  65. //重设(主结构)请求;更新当前配置
  66. static ULONG manageTablesRequest (manageTablesReq *u);
  67. //收索对应的地址
  68. USHORT treeLookup (addrTreeNode *tbl, ULONG addr, unsigned short max_group);
  69. //检查入站的tcp包
  70. static ULONG checkIncomingTcp (ULONG srcAddr, ULONG dstAddr,
  71.  unsigned short srcPort, unsigned short dstPort);
  72. //检查出站的tcp包
  73. static ULONG checkOutgoingTcp (ULONG srcAddr, ULONG dstAddr,
  74.  unsigned short srcPort, unsigned short dstPort);
  75. //检查入站的udp
  76. static ULONG checkIncomingUdp (ULONG srcAddr, ULONG dstAddr,
  77.  unsigned short srcPort, unsigned short dstPort);
  78. //检查出站udp
  79. static ULONG checkOutgoingUdp (ULONG srcAddr, ULONG dstAddr,
  80.  unsigned short srcPort, unsigned short dstPort);
  81. //检查入站的icmp类型
  82. static ULONG checkIncomingIcmp (ULONG srcAddr, ULONG dstAddr, unsigned char type);
  83. //检查入站的icmp类型
  84. static ULONG checkOutgoingIcmp (ULONG srcAddr, ULONG dstAddr, unsigned char type);
  85. //检查入DM的tcp(无)
  86. static ULONG checkIncomingDMTcp (ULONG srcAddr, ULONG dstAddr,
  87.  unsigned short srcPort, unsigned short dstPort);
  88. //检查入DM的udp(无)
  89. static ULONG checkIncomingDMUdp (ULONG srcAddr, ULONG dstAddr,
  90.  unsigned short srcPort, unsigned short dstPort);
  91. //检查入DM的icmp(无)
  92. static ULONG checkIncomingDMIcmp(ULONG srcAddr, ULONG dstAddr, unsigned char type);
  93. //检查拒绝表
  94. static ULONG checkRejectTable (ip *ipHeader, ULONG srcAddr, ULONG dstAddr);
  95. //static ULONG checkIncomingPacket (unsigned char *pkt,unsigned char protolen);
  96. //检查入站包
  97. static ULONG checkIncomingPacket(USHORT,BYTE*,ULONG,ULONG);
  98. //检查允许表
  99. static ULONG checkAcceptTable (struct ip *ipHeader, ULONG srcAddr, ULONG dstAddr);//END:GJ
  100. //检查出站包
  101. static ULONG checkOutgoingPacket (unsigned short protocol,unsigned char *pkt,unsigned short protolen);
  102. //现无
  103. static ULONG checkIncomingDM(ULONG srcAddr, ULONG dstAddr,
  104.  unsigned short srcPort, unsigned short dstPort,UCHAR from);
  105. //初始化包过滤请求
  106. static ULONG initRequest (initReq *req);
  107. //校验和
  108. extern USHORT  GetCksum(USHORT* buffer,int size);
  109. USHORT in_cksum_tcp(BYTE *buffer);//gj
  110. BOOL   in_cksum_hdr(BYTE* buffer);
  111. //input eth and calculate checksum
  112. struct pkt_struct *mtodPkt(BYTE *r)
  113. {
  114.     struct pkt_struct *pkt;
  115. pkt=(struct pkt_struct *)r[14];
  116.     return pkt;
  117. }
  118. //input eth and calculate checksum
  119. USHORT in_cksum_tcp(BYTE* buffer)
  120. {
  121.     //BYTE* tempbuffer;
  122. USHORT  tcpleng;
  123. USHORT  tcpchecksum;
  124. USHORT*  tempushort;
  125. USHORT  IPleng;
  126. //
  127. BYTE*   tempbuffer;
  128. //set checksum=0;
  129. buffer[34+16] = 0;
  130. buffer[34+17] = 0;
  131.     //getIPleng(total)
  132.     ((BYTE*)(&IPleng))[0] = buffer[17];
  133.     ((BYTE*)(&IPleng))[1] = buffer[16];
  134. //get tcpleng(total)
  135. tcpleng = IPleng - 20;
  136.     
  137. //get pseudo head
  138. tempbuffer = new BYTE[tcpleng+12];
  139. memcpy(tempbuffer+12,buffer+34,tcpleng);
  140. tempbuffer[0] = buffer[26];
  141. tempbuffer[1] = buffer[27];
  142. tempbuffer[2] = buffer[28];
  143. tempbuffer[3] = buffer[29];
  144. tempbuffer[4] = buffer[30];
  145. tempbuffer[5] = buffer[31];
  146. tempbuffer[6] = buffer[32];
  147. tempbuffer[7] = buffer[33];
  148.         tempbuffer[8] = 0;
  149. tempbuffer[9] = 6;
  150. tempbuffer[10] = ((BYTE*)(&tcpleng))[1];
  151. tempbuffer[11] = ((BYTE*)(&tcpleng))[0];
  152.         
  153. tempushort = (USHORT*) tempbuffer;
  154. tcpchecksum = GetCksum(tempushort, tcpleng+12);
  155. buffer[34+16] = ((BYTE*)(&tcpchecksum))[0];
  156. buffer[34+17] = ((BYTE*)(&tcpchecksum))[1];
  157. return tcpchecksum;
  158. }
  159. //input eth and calculate checksum
  160. BOOL in_cksum_hdr(BYTE* buffer)
  161. {
  162. BYTE* tempbufferttt;
  163. USHORT* tempushortbuffer;
  164. USHORT  checksum;
  165. tempbufferttt = &buffer[14];
  166. tempushortbuffer = (USHORT* )tempbufferttt;
  167. tempushortbuffer[5] = 0;
  168.     checksum = GetCksum(tempushortbuffer,20);
  169. tempushortbuffer[5] = checksum;
  170.     return TRUE;
  171. }
  172. /*
  173. //input buffer  and calculate checksum
  174. USHORT  GetCksum(USHORT* buffer,ULONG size)
  175. {
  176. DWORD cksum;
  177. USHORT OddByte;
  178. cksum=0;
  179. while(size>1)
  180. {
  181. cksum+=*buffer++;
  182. size-=2;
  183. }
  184. if(size==1)
  185. {
  186.         OddByte = 0;
  187. *((unsigned char*)&OddByte)= *(unsigned char*)buffer;
  188. cksum+=OddByte;
  189. }
  190. cksum=(cksum>>16)+(cksum&0xffff);
  191. cksum+=(cksum>>16);
  192. cksum=~cksum;
  193.     return (unsigned short)cksum;
  194. }
  195. */
  196. static ULONG checkIncomingDM(ULONG srcAddr, ULONG dstAddr,
  197.  unsigned short srcPort, unsigned short dstPort,UCHAR from)
  198. {
  199. USHORT group;
  200. //查找目的地址是否是组播
  201. if (IN_CLASSD(dstAddr)) //0xe0000000~0xef000000
  202. {
  203. if (filtercfg.discardMulticast)
  204. {
  205. filterstats.f_insideMcast++;
  206. syslogMessage(SYSL_OUT_CLASSD,IP_PROTO_TCP,
  207. srcAddr, dstAddr, srcPort, dstPort);
  208. return DISCARD_PKT;
  209. }
  210. return ALLOW_PKT;
  211. }
  212.     if(from=FROMOUT)
  213.    group = treeOutLookup(active.Out_DmTree, srcAddr, active.num_groups);
  214. else
  215.    group = treeLookup(active.In_DmTree, srcAddr, active.num_groups);
  216.     if(group==1)
  217.        return ALLOW_PKT;
  218. syslogMessage(SYSL_IN_REJECT,NULL,
  219.          srcAddr, dstAddr);
  220.     return DISCARD_PKT;
  221. }
  222. // 所有参数都是主机顺序。
  223. // 注意:如果下面的表改变,在ipfilter.h中的enum结构也要改变。
  224. // 注意: DM的日志
  225. // log函数
  226. static SyslogMessageEntry syslogMessages[] = {
  227. { "入组播", LOG_WARNING },// SYSL_IN_CLASSD,
  228. { "出组播", LOG_WARNING },// SYSL_OUT_CLASSD,
  229. { "入端口", LOG_WARNING },// SYSL_IN_PORT,
  230. { "出端口", LOG_WARNING },// SYSL_OUT_PORT, /* only TCP */
  231. { "入协议头太短", LOG_WARNING },// SYSL_IN_LENGTH, /* TCP/UDP-Header maybe not initialized */
  232. { "出协议头太短", LOG_WARNING },// SYSL_IN_DOS, /* denial of service attack packet in */
  233. { "入ICMP类型", LOG_WARNING },// SYSL_IN_TYPE, /* only srcAddr, dstAddr, and icmp type */
  234. { "出ICMP类型", LOG_WARNING },// SYSL_OUT_TYPE, /* only srcAddr, dstAddr, and icmp type */
  235. { "入拒绝IP", LOG_WARNING },// SYSL_IN_REJECT, /* only protocolNo, srcAddr and dstAddr */
  236. { "出拒绝IP", LOG_WARNING },// SYSL_OUT_ACCEPT, /* only protocolNo, srcAddr and dstAddr */
  237. { "入非IP", LOG_NOTICE  },// SYSL_IN_PROT, /* only protocolNo, srcAddr and dstAddr */
  238. { "出非IP", LOG_WARNING },// SYSL_OUT_PROT, /* only protocolNo, srcAddr and dstAddr */
  239. { "入偏移量为1", LOG_WARNING },// SYSL_IN_OFFSET, /* suspect fragment offset */
  240. { "出偏移量为1", LOG_WARNING },// SYSL_OUT_OFFSET, /* suspect fragment offset */
  241. { "入分段", LOG_WARNING },// SYSL_IN_FRAG, /* fragmented packet */
  242. { "出分段", LOG_WARNING },// SYSL_OUT_FRAG, /* fragmented packet */
  243. { "入D_O_S攻击", LOG_WARNING },// SYSL_IN_DOS, /* denial of service attack packet in */
  244. { "出D_O_S攻击", LOG_WARNING },// SYSL_OUT_DOS, /* denial of service attack packet out */
  245. {"原路由攻击",LOG_WARNING},
  246. {"入ICMP",LOG_WARNING},
  247. {"出ICMP",LOG_WARNING},
  248. {"入IGMP",LOG_WARNING},
  249. {"出IGMP",LOG_WARNING},
  250. };
  251. static const char *syslogDosTypes[] = { ""Smurf"", ""Pong"" };
  252. //Config.cpp中添加日志请求
  253. static void
  254. syslogMessage(unsigned char eventNo,ULONG protocolNo,ULONG srcaddr,
  255.   ULONG dstaddr, unsigned short srcport,unsigned short dstport,
  256.   unsigned char icmptype,UCHAR dostype)
  257. {
  258. //如果该日志被禁止,就返回。
  259. if ( !((1UL << eventNo) & filtercfg.logMask))
  260. return;
  261. char tempchar[10];
  262. SYSTEMTIME  SystemTime;
  263. GetLocalTime(&SystemTime);
  264. char cdstaddr[16];
  265. char csrcaddr[16];
  266.     struct in_addr dstin,srcin;
  267. dstin.S_un.S_addr=htonl(dstaddr);
  268. srcin.S_un.S_addr=htonl(srcaddr);
  269.     memcpy(cdstaddr,inet_ntoa(dstin),16);
  270.     memcpy(csrcaddr,inet_ntoa(srcin),16);
  271. switch ( eventNo ) {
  272. case SYSL_IN_OFFSET:
  273. case SYSL_OUT_OFFSET:
  274. case SYSL_IN_FRAG:
  275. case SYSL_OUT_FRAG:
  276. case SYSL_IN_REJECT:
  277. case SYSL_OUT_ACCEPT:
  278. case SYSL_IN_PROT: 
  279. case SYSL_OUT_PROT: 
  280. case SYSL_OUT_ROUT:
  281.         case SYSL_IN_ICMP:
  282. case SYSL_OUT_ICMP:
  283. case SYSL_IN_IGMP:
  284. case SYSL_OUT_IGMP:
  285. { /* IP - general */
  286.      switch(protocolNo)
  287. {
  288.      case IP_PROTO_TCP:
  289.     strcpy(tempchar,"TCP");
  290.      break;
  291.     case IP_PROTO_UDP:
  292.     strcpy(tempchar,"UDP");
  293.     break;
  294.     case IP_PROTO_ICMP:
  295.     strcpy(tempchar,"ICMP");
  296.     break;
  297. case IP_PROTO_IGMP:
  298. strcpy(tempchar,"IGMP");
  299.     default:
  300. strcpy(tempchar,"");
  301.     break;
  302. }
  303. /* sprintf(filterlog.str[filterlog.pos],"时间:%d月%d日%d:%d:%dt说明:%st协议:%stFrom:%s" "To:%sn",
  304. SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  305. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  306. tempchar,csrcaddr,cdstaddr);
  307. filterlog.pos++;
  308. */          if(logType==1)
  309. {
  310.             sprintf(logview.time,"%d月%d日%d:%d:%d",SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  311.       SystemTime.wMinute,SystemTime.wSecond);
  312.             strcpy(logview.prot,tempchar);
  313. strcpy(logview.src,csrcaddr);
  314. strcpy(logview.dst,cdstaddr);
  315. strcpy(logview.demo,syslogMessages[eventNo].message);
  316.             //PostMessage(AfxGetMainWnd()->GetSafeHwnd(),M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  317.             PostMessage(myhWnd1,M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  318. }
  319. fprintf(hlogFile,"时间:%d月%d日%d:%d:%dt说明:%st协议:%stFrom:%s" "To:%sn"
  320. ,SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  321. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  322. tempchar,csrcaddr,cdstaddr);
  323.               filtercount++;
  324. break;
  325. }
  326. case SYSL_IN_CLASSD:
  327. case SYSL_OUT_CLASSD:
  328. case SYSL_IN_PORT:
  329. case SYSL_OUT_PORT:
  330. case SYSL_IN_LENGTH:
  331. case SYSL_OUT_LENGTH:
  332. { /* IP - TCP/UDP */
  333.   strcpy(tempchar,(protocolNo == IP_PROTO_UDP) ? "UDP" : "TCP");
  334. /*   sprintf(filterlog.str[filterlog.pos],"时间:%d月%d日%d:%d:%dt说明:%st协议:%stFrom%s:%d"  "To%s:%dn",
  335. SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  336. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  337. tempchar,csrcaddr,ntohs(srcport),cdstaddr,ntohs(dstport));
  338.   filterlog.pos++;
  339. */
  340. if(logType==1)
  341.             {
  342.             memset((char*)&logview,0,sizeof(LOGVIEW));
  343. sprintf(logview.time,"%d月%d日%d:%d:%d",SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  344.       SystemTime.wMinute,SystemTime.wSecond);
  345.             strcpy(logview.prot,tempchar);
  346. sprintf(logview.src,"%s:%d",csrcaddr,ntohs(srcport));
  347. sprintf(logview.dst,"%s:%d",cdstaddr,ntohs(dstport));
  348. strcpy(logview.demo,syslogMessages[eventNo].message);
  349.             PostMessage(myhWnd1,M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  350.  //           PostMessage(AfxGetMainWnd()->GetSafeHwnd(),M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  351. }
  352.   fprintf(hlogFile,"时间:%d月%d日%d:%d:%dt说明:%st协议:%stFrom%s:%d"  "To%s:%dn"
  353. ,SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  354. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  355. tempchar,csrcaddr,ntohs(srcport),cdstaddr,ntohs(dstport));
  356.               filtercount++;
  357.           break;
  358. }
  359. case SYSL_IN_TYPE:  /* IP - ICMP */
  360. case SYSL_OUT_TYPE:
  361. {
  362. /*   sprintf(filterlog.str[filterlog.pos],"时间:%d月%d日%d:%d:%dt说明:%stFrom%s"  "To%stICMP类型:%dn",
  363. SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  364. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  365. csrcaddr,cdstaddr,icmptype);
  366.   filterlog.pos++;
  367. */
  368.     strcpy(tempchar,"ICMP");
  369. if(logType==1)
  370. {
  371.             memset((char*)&logviewIcmp,0,sizeof(LOGVIEWICMP));
  372. sprintf(logviewIcmp.time,"%d月%d日%d:%d:%d",SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  373.       SystemTime.wMinute,SystemTime.wSecond);
  374.             strcpy(logviewIcmp.prot,tempchar);
  375. strcpy(logviewIcmp.src,csrcaddr);
  376. strcpy(logviewIcmp.dst,cdstaddr);
  377. strcpy(logviewIcmp.demo,syslogMessages[eventNo].message);
  378. sprintf(logviewIcmp.type,"%d",icmptype);
  379.    //         PostMessage(AfxGetMainWnd()->GetSafeHwnd(),M_LOGVIEW,(WPARAM)&logviewIcmp,(LPARAM)112);
  380.             PostMessage(myhWnd1,M_LOGVIEW,(WPARAM)&logviewIcmp,(LPARAM)112);
  381. }
  382.   fprintf(hlogFile,"时间:%d月%d日%d:%d:%dt说明:%stFrom%s"  "To%stICMP类型:%dn",
  383. SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  384. SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,
  385. csrcaddr,cdstaddr,icmptype);
  386.               filtercount++;
  387.               break;
  388. }
  389. case SYSL_IN_DOS: /* DOS 攻击 */
  390. case SYSL_OUT_DOS:
  391. {
  392. /*   sprintf(filterlog.str[filterlog.pos],"时间:%d月%d日%d:%d:%dt说明:%stDOS类型:%dtFrom%s"  "To%sn",
  393. SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  394.   SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,syslogDosTypes[dostype],
  395.     csrcaddr,cdstaddr);
  396.   filterlog.pos++;
  397. */
  398.             if(logType==1)
  399.             {
  400.             memset((char*)&logview,0,sizeof(LOGVIEW));
  401. sprintf(logview.time,"%d月%d日%d:%d:%d",SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  402.       SystemTime.wMinute,SystemTime.wSecond);
  403. strcpy(logview.src,csrcaddr);
  404. strcpy(logview.dst,cdstaddr);
  405. strcpy(logview.demo,syslogMessages[eventNo].message);
  406.     //        PostMessage(AfxGetMainWnd()->GetSafeHwnd(),M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  407.             PostMessage(myhWnd1,M_LOGVIEW,(WPARAM)&logview,(LPARAM)111);
  408. }
  409.   fprintf(hlogFile,"时间:%d月%d日%d:%d:%dt说明:%stDOS类型:%dtFrom%s"  "To%sn"
  410. ,SystemTime.wMonth,SystemTime.wDay,SystemTime.wHour,
  411.   SystemTime.wMinute,SystemTime.wSecond,syslogMessages[eventNo].message,syslogDosTypes[dostype],
  412.     csrcaddr,cdstaddr);
  413.               filtercount++;
  414.   break;
  415. }
  416. /*
  417. if(filterlog.pos==1000)
  418. {
  419.             fwrite(filterlog.str,sizeof(char),filterlog.pos*100,hlogFile);
  420. memset(&filterlog,0,sizeof(FilterLog));
  421. filterlog.pos=0;
  422.                 writestatistic();
  423. fprintf(statFile,"n");
  424. fclose(statFile);
  425.             fclose(hlogFile);
  426. hlogFile=fopen("日志.txt","a");
  427.             statFile=fopen("统计.txt","a");
  428. }
  429. */
  430. if(filtercount==100)
  431. {
  432. memset(&filterstats,0,sizeof(Statistics));
  433. filtercount=0;
  434.                 writestatistic();
  435. fprintf(statFile,"n");
  436. fclose(statFile);
  437.             fclose(hlogFile);
  438. hlogFile=fopen("日志.txt","a");
  439.             statFile=fopen("统计.txt","a");
  440. }
  441. }
  442. }
  443. /* ------------------------------------------------------------------------ */
  444. static void
  445. freeAllPointers(pointerStruct *p)
  446. {//在free函数中去掉了M_DEVBUF参数;此参数在头文件中
  447. if (p->addrTree) freeTree(p->addrTree, 0);
  448. if (p->t_dst_out) free(p->t_dst_out);
  449.         if (p->t_src_out) free(p->t_src_out);
  450.         if (p->u_dst_out) free(p->u_dst_out);
  451.         if (p->u_src_out) free(p->u_src_out);
  452.         if (p->i_typ_in) free(p->i_typ_in);
  453.         if (p->i_typ_out) free(p->i_typ_out);
  454.         if (p->t_rst_in) free(p->t_rst_in);
  455.         if (p->t_rst_out) free(p->t_rst_out);
  456.         if (p->acceptTable) free(p->acceptTable);
  457.         if (p->acceptTree) freeTree(p->acceptTree, 0);
  458.         if (p->rejectTable) free(p->rejectTable);
  459.         if (p->rejectTree) freeOutTree(p->rejectTree, 0);
  460.         if(p->In_DmTree)freeTree(p->In_DmTree,0);
  461.         if(p->Out_DmTree)freeOutTree(p->Out_DmTree,0);
  462. memset(p,0,sizeof(pointerStruct));
  463. }
  464. /* ------------------------------------------------------------------------ */
  465. //groups:最多可设定的主机类的数目
  466. static ULONG
  467. initTables(pointerStruct *p, unsigned short groups)
  468. {
  469. /* 必须至少有一类 */
  470. if (groups == 0)
  471. groups = 1;
  472. /* 释放所有由指针结构分配的空间*/
  473. freeAllPointers(p);
  474. /* 建立一个缺省配置 */
  475. p->addrTree  = MALLOC_NODE;
  476.  //groups*32*sizeof(PortListEntry)
  477. p->t_dst_out = MALLOC_GROUP(groups);
  478. p->t_src_out = MALLOC_GROUP(groups);
  479. p->u_dst_out = MALLOC_GROUP(groups);
  480. p->u_src_out = MALLOC_GROUP(groups);
  481. p->i_typ_in  = MALLOC_GROUP(groups);
  482. p->i_typ_out = MALLOC_GROUP(groups);
  483. p->t_rst_in  = MALLOC_GROUP(groups);
  484. p->t_rst_out = MALLOC_GROUP(groups);
  485. if ((p->addrTree == NULL) ||
  486.     (p->t_dst_out == NULL) ||(p->t_src_out == NULL) ||
  487.         (p->u_dst_out == NULL) ||(p->u_src_out == NULL) ||
  488.     (p->i_typ_in  == NULL) || (p->i_typ_out == NULL) ||
  489.     (p->t_rst_in  == NULL) || (p->t_rst_out == NULL)) {
  490. freeAllPointers(p);
  491. return ERROR_NO_MEMORY;
  492. }
  493. p->num_groups = groups;
  494. memset(p->addrTree, 0, sizeof(addrTreeNode));
  495. memset(p->t_dst_out,0,groups * LIST_TABLE_SIZE);
  496. memset(p->t_src_out,0,groups * LIST_TABLE_SIZE);
  497. memset(p->u_dst_out,0,groups * LIST_TABLE_SIZE);
  498. memset(p->u_src_out,0,groups * LIST_TABLE_SIZE);
  499. memset(p->i_typ_in,0,groups * LIST_TABLE_SIZE);
  500. memset(p->i_typ_out,0,groups * LIST_TABLE_SIZE);
  501. memset(p->t_rst_in,0,LIST_TABLE_SIZE);
  502. memset(p->t_rst_out,0,LIST_TABLE_SIZE);
  503. /* 填写缺省类表*/
  504. switch(TheDefaultSetData.Priority)
  505. {
  506. case 0://high
  507.         p->t_dst_out[0].begin = 2; // TCP - 1个 
  508.         p->t_dst_out[1].begin = 80; // TCP -http out    
  509.         p->t_dst_out[1].end = 80;
  510.         p->t_dst_out[2].begin=1024;//>=1024 OUT
  511.     p->t_dst_out[2].begin=0xFFFF;
  512.         
  513. p->t_src_out[0].begin=1;
  514.     p->t_src_out[1].begin=1024;
  515.     p->t_src_out[1].end=0xFFFF;
  516.     p->u_src_out[0].begin=1;
  517.     p->u_src_out[1].begin=1024;
  518.         p->u_src_out[1].end=0xFFFF;
  519.     p->u_dst_out[0].begin = 1; ///* UDP - 1个
  520.     p->u_dst_out[1].begin = 1024; ///* UDP >=1024 out    
  521.     p->u_dst_out[1].end = 0xFFFF;
  522.     p->i_typ_in[0].begin = 1; ///* ICMP - 1个
  523.     p->i_typ_in[1].begin = 0; ///* ICMP - FORBID      
  524.     p->i_typ_in[1].end = 0;
  525.     p->i_typ_out[0].begin = 1; //* ICMP - 1个
  526.     p->i_typ_out[1].begin = 0; //* ICMP - FORBID       
  527.     p->i_typ_out[1].end = 0;
  528. break;
  529. case 1://middle
  530.         p->t_dst_out[0].begin = 5; // TCP - 1个 
  531.         p->t_dst_out[1].begin = 80; // TCP -http out    
  532.         p->t_dst_out[1].end = 80;
  533.         p->t_dst_out[2].begin =20; // TCP -FTP TELNET out    
  534.         p->t_dst_out[2].end = 23;
  535.         p->t_dst_out[3].begin =137; // TCP -NBT out    
  536.         p->t_dst_out[3].end =139;
  537.         p->t_dst_out[4].begin =161; // TCP -SNMP out    
  538.         p->t_dst_out[4].end = 162;
  539. p->t_dst_out[5].begin=1024;//>=1024 OUT
  540.     p->t_dst_out[5].begin=0xFFFF;
  541.         
  542. p->t_src_out[0].begin=1;
  543.     p->t_src_out[1].begin=0;
  544.     p->t_src_out[1].end=0xFFFF;
  545.     p->u_src_out[0].begin=1;
  546.     p->u_src_out[1].begin=0;
  547.         p->u_src_out[1].end=0xFFFF;
  548.     p->u_dst_out[0].begin = 1; ///* UDP - 1个
  549.     p->u_dst_out[1].begin = 1024; ///* UDP >=1024 out    
  550.     p->u_dst_out[1].end = 0xFFFF;
  551.     p->i_typ_in[0].begin = 1; ///* ICMP - 1个
  552.     p->i_typ_in[1].begin = 0; ///* ICMP - everything out 
  553.     p->i_typ_in[1].end = 0xFF;
  554.     p->i_typ_out[0].begin = 1; //* ICMP - 1个
  555.     p->i_typ_out[1].begin = 0; //* ICMP - everything out       
  556.     p->i_typ_out[1].end = 0xFF;
  557. break;
  558. case 2://low
  559.         p->t_dst_out[0].begin = 5; // TCP - 1个 
  560.         p->t_dst_out[1].begin = 80; // TCP -http out    
  561.         p->t_dst_out[1].end = 80;
  562.         p->t_dst_out[2].begin =20; // TCP -FTP TELNET out    
  563.         p->t_dst_out[2].end = 23;
  564.         p->t_dst_out[3].begin =137; // TCP -NBT out    
  565.         p->t_dst_out[3].end =139;
  566.         p->t_dst_out[4].begin =161; // TCP -SNMP out    
  567.         p->t_dst_out[4].end = 162;
  568. p->t_dst_out[5].begin=1024;//>=1024 OUT
  569.     p->t_dst_out[5].begin=0xFFFF;
  570.         
  571. p->t_src_out[0].begin=1;
  572.     p->t_src_out[1].begin=0;
  573.     p->t_src_out[1].end=0xFFFF;
  574.     p->u_src_out[0].begin=1;
  575.     p->u_src_out[1].begin=0;
  576.         p->u_src_out[1].end=0xFFFF;
  577.     p->u_dst_out[0].begin = 2; ///* UDP - 1个
  578.     p->u_dst_out[1].begin = 53; ///* UDP dns out    
  579.     p->u_dst_out[1].end = 53;
  580.     p->u_dst_out[1].begin =1024;
  581.     p->u_dst_out[1].end = 0xFFFF;
  582.     p->i_typ_in[0].begin = 1; ///* ICMP - 1个
  583.     p->i_typ_in[1].begin = 0; ///* ICMP - everything out 
  584.     p->i_typ_in[1].end = 0xFF;
  585.     p->i_typ_out[0].begin = 1; //* ICMP - 1个
  586.     p->i_typ_out[1].begin = 0; //* ICMP - everything out       
  587.     p->i_typ_out[1].end = 0xFF;
  588. break;
  589. default://high
  590.         p->t_dst_out[0].begin = 2; // TCP - 1个 
  591.         p->t_dst_out[1].begin = 80; // TCP -http out    
  592.         p->t_dst_out[1].end = 80;
  593.         p->t_dst_out[2].begin=1024;//>=1024 OUT
  594.     p->t_dst_out[2].begin=0xFFFF;
  595.         
  596. p->t_src_out[0].begin=1;
  597.     p->t_src_out[1].begin=1024;
  598.     p->t_src_out[1].end=0xFFFF;
  599.     p->u_src_out[0].begin=1;
  600.     p->u_src_out[1].begin=1024;
  601.         p->u_src_out[1].end=0xFFFF;
  602.     p->u_dst_out[0].begin = 1; ///* UDP - 1个
  603.     p->u_dst_out[1].begin = 1024; ///* UDP >=1024 out    
  604.     p->u_dst_out[1].end = 0xFFFF;
  605.     p->i_typ_in[0].begin = 1; ///* ICMP - 1个
  606.     p->i_typ_in[1].begin = 0; ///* ICMP - FORBID      
  607.     p->i_typ_in[1].end = 0;
  608.     p->i_typ_out[0].begin = 1; //* ICMP - 1个
  609.     p->i_typ_out[1].begin = 0; //* ICMP - FORBID       
  610.     p->i_typ_out[1].end = 0;
  611. }
  612. return NOO_ERROR;
  613. }
  614. /*-----------------------------------------------------------------------*/
  615. static void
  616. freeTree(addrTreeNode *tbl, unsigned char level)
  617. {
  618.         ULONG i;
  619.         if (!tbl || (level >1)) 
  620. {
  621. //参数错误
  622.                 return;
  623. }
  624.         for (i=0; i<256; i++) 
  625. {
  626.                 if (tbl->u[i].pd)
  627. {
  628.         free(tbl->u[i].pd);
  629. }
  630. }
  631. free(tbl);
  632. }
  633. static ULONG
  634. copyGroup(portListReq *u, PortListEntry *kptr)
  635. {
  636. if (kptr == NULL)
  637. return ERROR_NET_NOT_FOUND; 
  638. //准确的添加到尾
  639.  USHORT pos=kptr[0].begin;
  640.      kptr[0].begin+=u->bytes/sizeof(PortListEntry);
  641.  if(pos==0)
  642.  pos++;
  643.  memcpy(&kptr[pos],u->ptr, u->bytes);//需要判断已经设定的端口数
  644.  return u->bytes;
  645. }
  646. /* ------------------------------------------------------------------------ */
  647. static ULONG
  648. portListRequest(portListReq *u, pointerStruct *p)
  649. {
  650. //u->group:当前的主机类
  651. ULONG byte=u->bytes*sizeof(PortListEntry);
  652. ULONG ret=u->group + ((byte/ LIST_TABLE_SIZE) +
  653.         (byte% LIST_TABLE_SIZE) ? 1 : 0);
  654. if (ret > p->num_groups)
  655. return ERROR_OUT_OF_RANGE;
  656. switch (u->id) {
  657. case T_DST_OUT:
  658. return copyGroup(u ,&(p->t_dst_out[(u->group-1)  * LIST_SIZE]));
  659. case T_SRC_OUT:
  660. return copyGroup(u ,&(p->t_src_out[(u->group-1) * LIST_SIZE]));
  661. case U_DST_OUT:
  662. return copyGroup(u ,&(p->u_dst_out[(u->group-1) * LIST_SIZE]));
  663. case U_SRC_OUT:
  664. return copyGroup(u ,&(p->u_src_out[(u->group-1) * LIST_SIZE]));
  665. case I_TYP_IN:
  666. return copyGroup(u ,&(p->i_typ_in[(u->group-1) * LIST_SIZE]));
  667. case I_TYP_OUT:
  668. return copyGroup(u ,&(p->i_typ_out[(u->group-1) * LIST_SIZE]));
  669. case T_RST_IN:
  670. if (u->group > 1)
  671. return ERROR_OUT_OF_RANGE;
  672. return copyGroup(u, p->t_rst_in);
  673. case T_RST_OUT:
  674. if (u->group > 1)
  675. return ERROR_OUT_OF_RANGE;
  676. return copyGroup(u, p->t_rst_out);
  677. default:
  678. return ERROR_UNKNOWN_GROUP;
  679. }
  680. }
  681. /* ------------------------------------------------------------------------ */
  682. static ULONG
  683. addrTreeRequest(addrTreeReq *u)
  684. {
  685. register unsigned char i;
  686.     if (newspace.addrTree == NULL) 
  687. return ERROR_NET_NOT_FOUND; 
  688. /* Add the specified IP cidr(s) to the 'newspace' config */
  689. //最多128个ip地址(可能是每个主机类的起始ip)(即最多128个主机类)
  690. for (i=0; (i < u->num) && (i < 128); i++) {
  691. if (GjaddToTree(newspace.addrTree, u->addr[i],
  692.      u->bits[i], u->group[i])) {
  693. freeTree(newspace.addrTree, 0);
  694. newspace.addrTree = NULL;
  695. return ERROR_NO_MEMORY;
  696. }
  697. }
  698. return NOO_ERROR;
  699. }
  700. /* ------------------------------------------------------------------------ */
  701. static int
  702. OutrejaccTableRequest(int id, rejaccTableReq *u, pointerStruct *p)
  703. {
  704. register unsigned char i;
  705. RejAccTableEntry *table;   //允许拒绝表
  706. OutaddrTreeNode *tree;        //地址树,用于包过滤
  707. //u->bytes必须是sizeof(RejAccTableEntry)的整数倍
  708. if ((u->bytes == 0) || (u->bytes % sizeof(RejAccTableEntry)))
  709. return ERROR_INVALID_OP;
  710. //为树分配空间  
  711. table = (RejAccTableEntry *)malloc(u->bytes);//,M_DEVBUF,M_NOWAIT);
  712. if (table == NULL)
  713. return ERROR_NO_MEMORY;
  714. tree = MALLOC_OUTNODE;
  715. if (tree == NULL)
  716. {
  717. free(table);//);
  718. return ERROR_NO_MEMORY;
  719. memset(tree,0,sizeof(addrTreeNode));
  720. memset(table,0, u->bytes);
  721.     memcpy(table, u->ptr, u->bytes);//gj
  722. // return u->bytes;//gj
  723. // Populate the tree from the table - keep the table around
  724. // to spit back out when requested by the user interface.
  725. for (i=u->bytes/sizeof(RejAccTableEntry); i; i--) {
  726. register int r;
  727. //将拒绝的IP地址添加到树
  728. if ((r=OutnetaddToTree(tree, table[i-1].network,
  729. table[i-1].bits, table[i-1].flag))) {
  730. freeOutTree(tree, 0);
  731. free(table);//);
  732. return (r>0) ? ERROR_NO_MEMORY :
  733. ERROR_INVALID_OP;
  734. }
  735. }
  736. //传到主结构
  737.  switch(id)
  738.  {
  739.    case T_REJTBL:
  740. if ((p->rejectTable != NULL) || (p->rejectTree != NULL))
  741. {
  742. free(p->rejectTable);
  743. freeOutTree(p->rejectTree,0);
  744. p->rejectTable = table;
  745. p->rejectTree = tree;
  746. p->reject_bytes = u->bytes;
  747. break;
  748.    case T_OUTDM:
  749.  if (p->Out_DmTree!= NULL)
  750. freeOutTree(p->Out_DmTree,0);
  751. p->Out_DmTree = tree;
  752. free(table);
  753.    break;
  754.    default:
  755.    freeOutTree(tree,0);
  756.    free(table);
  757.    return ERROR_INVALID_OP;
  758.  }
  759. return NOO_ERROR;
  760. }
  761. /* ------------------------------------------------------------------------ */
  762. static ULONG
  763. rejaccTableRequest(ULONG id, rejaccTableReq *u, pointerStruct *p)
  764. {
  765. register unsigned char i;
  766. RejAccTableEntry *table;   //允许拒绝表
  767. addrTreeNode *tree;        //地址树,用于包过滤
  768. //u->bytes必须是sizeof(RejAccTableEntry)的整数倍
  769. if ((u->bytes == 0) || (u->bytes % sizeof(RejAccTableEntry)))
  770. return ERROR_INVALID_OP;
  771. //为树分配空间  
  772. table = (RejAccTableEntry *)malloc(u->bytes);//,M_DEVBUF,M_NOWAIT);
  773. if (table == NULL)
  774. return ERROR_NO_MEMORY;
  775. tree = MALLOC_NODE;
  776. if (tree == NULL)
  777. {
  778. free(table);//);
  779. return ERROR_NO_MEMORY;
  780. memset(tree,0,sizeof(addrTreeNode));
  781. memset(table,0, u->bytes);
  782.     memcpy(table, u->ptr, u->bytes);//gj
  783. // return u->bytes;//gj
  784. // Populate the tree from the table - keep the table around
  785. // to spit back out when requested by the user interface.
  786. for (i=u->bytes/sizeof(RejAccTableEntry); i; i--) {
  787. register ULONG r;
  788. //将拒绝的IP地址添加到树
  789. if ((r=GjaddToTree(tree, table[i-1].network,
  790. table[i-1].bits, table[i-1].flag))) {
  791. freeTree(tree, 0);
  792. free(table);//);
  793. return (r>0) ? ERROR_NO_MEMORY :
  794. ERROR_INVALID_OP;
  795. }
  796. }
  797. //传到主结构
  798.  switch(id)
  799.  {
  800.    case T_ACCTBL:
  801. if ((p->acceptTree != NULL) || (p->acceptTable!= NULL))
  802. {
  803. free(p->acceptTable);
  804. freeTree(p->acceptTree,0);
  805. p->acceptTable = table;
  806. p->acceptTree = tree;
  807. p->accept_bytes = u->bytes;
  808. break;
  809.    case T_INDM:
  810.  if (p->In_DmTree != NULL)
  811.   freeTree(p->In_DmTree,0);
  812.    p->In_DmTree = tree;
  813. free(table);
  814.    break;
  815.    default:
  816.    freeTree(tree,0);
  817.    free(table);
  818.    return ERROR_INVALID_OP;
  819.  }
  820. return NOO_ERROR;
  821. }
  822. static ULONG
  823. manageTablesRequest(manageTablesReq *u)
  824. {
  825. pointerStruct tmp;
  826. unsigned long rcode;
  827. switch (u->command) {
  828. //新配置设为当前配置,并清除原有配置
  829. case ACTIVATE_NEW:
  830. if ((newspace.num_groups == 0) || (newspace.addrTree == NULL) ||
  831.     (newspace.t_dst_out == NULL) ||(newspace.t_src_out == NULL) ||
  832.            (newspace.u_dst_out == NULL) ||(newspace.u_src_out == NULL) ||
  833.     (newspace.i_typ_in == NULL) || (newspace.i_typ_out == NULL) ||
  834.     (newspace.t_rst_in == NULL) || (newspace.t_rst_out == NULL))
  835. return ERROR_NET_NOT_FOUND;
  836. memcpy(&tmp, &active, sizeof(pointerStruct));
  837. memcpy(&active, &newspace, sizeof(pointerStruct));
  838. memset(&newspace,0,sizeof(pointerStruct));
  839. freeAllPointers(&tmp);
  840. break;
  841. //将用户配置设为缺省配置
  842. case CLEAR_ALL:
  843. rcode = initTables(&newspace, 1);
  844. if (rcode)
  845.  return rcode;
  846. memcpy(&tmp, &active, sizeof(pointerStruct));
  847. memcpy(&active, &newspace, sizeof(pointerStruct));
  848. memset(&newspace,0,sizeof(pointerStruct));
  849. freeAllPointers(&tmp);
  850. break;
  851. //在载入新配置前要重新初始化
  852. case INIT_NEW:
  853. rcode = initTables(&newspace, u->val);
  854. if (rcode)
  855. return rcode;
  856. break;
  857. }
  858. return NOO_ERROR;
  859. }
  860. /*-----------------------------------------------------------------------*/
  861. /*
  862.  *查找IP地址所属的类
  863.  */
  864. USHORT
  865. treeOutLookup(OutaddrTreeNode *tbl, ULONG addr, unsigned short max_group)
  866. {
  867.     addrTreePtr t1,t2;
  868. in_addr_t ip;
  869. if (tbl == NULL)
  870. return DEFAULT_ACCESS;
  871. // ip = (in_addr_t)addr;
  872. ip.ss_addr=addr;//gj..................
  873.         //查找地址的第一个八位     
  874. //flg=1: group ;   flg=0: pointer
  875.         if ((t1.p = tbl->u[ip.s_b[3]].p) == NULL)
  876.                 return DEFAULT_ACCESS;
  877.         if (tbl->flg[ip.s_b[3]])
  878.                 return ((t1.c < max_group) ? t1.c : DEFAULT_ACCESS);
  879.         //查找地址的第二个八位
  880.         //flg=1: group ;   flg=0: pointer
  881.         // t1.p = tbl->u[ip.s_b[3]].p
  882.       if ((t2.p = t1.p->u[ip.s_b[2]].p) == NULL)
  883.                 return DEFAULT_ACCESS;
  884.         if (t1.p->flg[ip.s_b[2]])
  885.                 return ((t2.c < max_group) ? t2.c : DEFAULT_ACCESS);
  886. //begin gj  //查找地址的第三个八位
  887.        if ((t1.p =t2.p->u[ip.s_b[1]].p) == NULL)
  888.                 return DEFAULT_ACCESS;
  889.        if (t2.p->flg[ip.s_b[1]])
  890.                 return ((t2.c < max_group) ? t2.c : DEFAULT_ACCESS);      
  891. //end gj
  892. //flg=1: group;    flg=0: pointer
  893.        //t2.p = tbl->u[ip.s_b[3]].p->u[ip.s_b[2]].p
  894. /*        if ((t1.pd = t2.p->u[ip.s_b[1]].pd) == NULL)
  895.     return DEFAULT_ACCESS;
  896.         if (t2.p->flg[ip.s_b[1]])
  897.                 return ((t1.c < max_group) ? t1.c : DEFAULT_ACCESS);
  898. */
  899. //查找地址的第四个八位
  900. //a group
  901.         // * t1.pd = tbl->u[ip.s_b[3]].p->u[ip.s_b[2]].p->u[ip.s_b[1]].pd
  902.         t2.c = t1.pd->c[ip.s_b[0]];
  903.         return ((t2.c < max_group) ? t2.c : DEFAULT_ACCESS);
  904. }
  905. USHORT
  906. treeLookup(addrTreeNode *tbl, ULONG addr, unsigned short max_group)
  907. {
  908. in_addr_t ip;
  909. if (tbl == NULL)
  910. return DEFAULT_ACCESS;
  911. // ip = (in_addr_t)addr;
  912. ip.ss_addr=addr;//gj..................
  913.         //查找地址的第一个八位     
  914. //flg=1: group ;   flg=0: pointer
  915. USHORT group;
  916. if(tbl->u[ip.s_b[1]].pd)
  917. {
  918. group=tbl->u[ip.s_b[1]].pd->c[ip.s_b[0]];
  919. return ((group<max_group)?group:DEFAULT_ACCESS);
  920. }
  921. else 
  922. return DEFAULT_ACCESS;
  923. }
  924. /* ------------------------------------------------------------------------ */
  925. //参数是主机顺序
  926. static ULONG
  927. checkIncomingTcp(ULONG srcAddr, ULONG dstAddr,
  928.  unsigned short srcPort, unsigned short dstPort)
  929. {
  930. //检查是否组播
  931. if (IN_CLASSD(dstAddr))//dstAddr是组播地址
  932. {
  933. if (filtercfg.discardMulticast)
  934. {
  935. filterstats.f_outsideMcast++;
  936. syslogMessage(SYSL_IN_CLASSD, IP_PROTO_TCP,
  937.        srcAddr, dstAddr, srcPort, dstPort);
  938. return DISCARD_PKT;
  939. }
  940. return ALLOW_PKT;
  941. }
  942. /*
  943. //通过目的地址从树中查找该地址所属的类
  944. group = treeLookup(active.addrTree, dstAddr, active.num_groups);
  945. if(group>0&&group<active.num_groups)
  946.    portList = &active.t_dst_in[(group-1) * LIST_SIZE];
  947. else
  948.      return DISCARD_PKT;
  949. //到该地址对应的目的端口设置处
  950. //查找目的端口是否允许
  951. for (i=1; i <= portList[0].begin; i++)
  952. {
  953. if ((dstPort >= portList[i].begin) &&
  954.     (dstPort <= portList[i].end))
  955.      return ALLOW_PKT;
  956. }
  957. //dstPort<1024则不检查源端口;直接禁止
  958. if (dstPort > 1024) 
  959. {
  960. //到该地址对应的源端口设置处
  961. portList = &active.t_src_in[group * LIST_SIZE];
  962. //比较源端口
  963. for (i=1; i <= portList[0].begin; i++)
  964. {
  965. if ((srcPort >= portList[i].begin) &&
  966.     (srcPort <= portList[i].end))
  967. return ALLOW_PKT;
  968. }
  969. }
  970. filterstats.f_outsideTcpPort++;
  971. // syslogMessage(SYSL_IN_PORT, IP_PROTO_TCP,
  972. //       srcAddr, dstAddr, (ULONG)srcPort, (ULONG)dstPort);
  973. //查找内网主机的TCP端口响应表(界面可加上)
  974. for (i=1; i <= active.t_rst_in[0].begin; i++)
  975. {
  976. if ((dstPort >= active.t_rst_in[i].begin) &&
  977.     (dstPort <= active.t_rst_in[i].end))
  978. {
  979. filterstats.outsideTCPreset++;
  980. return DISCARD_AND_ANSWER_PKT;
  981. }
  982. }
  983. */
  984. return DISCARD_PKT;
  985. }
  986. /* ------------------------------------------------------------------------ */
  987. static ULONG
  988. checkOutgoingTcp(ULONG srcAddr, ULONG dstAddr,
  989.  unsigned short srcPort, unsigned short dstPort)
  990. {
  991. ULONG i;
  992. ULONG group;
  993. PortListEntry *portList;
  994. //查找目的地址是否是组播
  995. if (IN_CLASSD(dstAddr)) 
  996. {
  997. if (filtercfg.discardMulticast)
  998. {
  999. filterstats.f_insideMcast++;
  1000. syslogMessage(SYSL_OUT_CLASSD,IP_PROTO_TCP,
  1001. srcAddr, dstAddr, srcPort, dstPort);
  1002. return DISCARD_PKT;
  1003. }
  1004. return ALLOW_PKT;
  1005. }
  1006. //通过源地址查找类
  1007. group = treeLookup(active.addrTree, srcAddr, active.num_groups);
  1008. if(group>0&&group<active.num_groups)
  1009. {
  1010. portList = &active.t_dst_out[(group-1) * LIST_SIZE];
  1011. }
  1012. else 
  1013.        return ALLOW_PKT;//未设置端口列表,默认所有的端口允许
  1014. //查找目的端口是否是允许出去访问的端口
  1015. for (i=1; i <= portList[0].begin; i++) 
  1016. {
  1017. if ((dstPort >= portList[i].begin) &&
  1018.     (dstPort <= portList[i].end))
  1019. return ALLOW_PKT;
  1020. }
  1021. if (dstPort > 1024)
  1022. {
  1023. portList = &active.t_src_out[group * LIST_SIZE];
  1024. for (i=1; i <= portList[0].begin; i++)
  1025. {
  1026. if ((srcPort >= portList[i].begin) &&
  1027.     (srcPort <= portList[i].end))
  1028. return ALLOW_PKT;
  1029. }
  1030. }
  1031. syslogMessage(SYSL_OUT_PORT,IP_PROTO_TCP,
  1032. srcAddr, dstAddr, srcPort, dstPort);
  1033. return DISCARD_PKT;
  1034. }
  1035. /* ------------------------------------------------------------------------ */
  1036. static ULONG
  1037. checkIncomingUdp(ULONG srcAddr, ULONG dstAddr,
  1038.  unsigned short srcPort, unsigned short dstPort)
  1039. {
  1040. // PortListEntry *portList;
  1041. if (IN_CLASSD(dstAddr)) 
  1042. {
  1043. if (filtercfg.discardMulticast) 
  1044. {
  1045. filterstats.f_outsideMcast++;
  1046. syslogMessage(SYSL_IN_CLASSD,IP_PROTO_UDP,
  1047. srcAddr, dstAddr, srcPort,dstPort);
  1048. return DISCARD_PKT;
  1049. }
  1050. return ALLOW_PKT;
  1051. }
  1052. syslogMessage(SYSL_IN_PORT, IP_PROTO_UDP,
  1053.       srcAddr, dstAddr, srcPort, dstPort);
  1054. return DISCARD_PKT;
  1055. }
  1056. /* ------------------------------------------------------------------------ */
  1057. static ULONG
  1058. checkOutgoingUdp(ULONG srcAddr, ULONG dstAddr,
  1059.  unsigned short srcPort, unsigned short dstPort)
  1060. {
  1061. register ULONG i;
  1062. ULONG group;
  1063. PortListEntry *portList;
  1064. if (IN_CLASSD(dstAddr)) {
  1065. if (filtercfg.discardMulticast) {
  1066. filterstats.f_insideMcast++;
  1067. syslogMessage(SYSL_OUT_CLASSD,IP_PROTO_UDP,
  1068. srcAddr, dstAddr,srcPort, dstPort);
  1069. return DISCARD_PKT;
  1070. }
  1071. return ALLOW_PKT;
  1072. }
  1073. group = treeLookup(active.addrTree, srcAddr, active.num_groups);
  1074.     if(group>0&&group<active.num_groups)
  1075. {
  1076. portList = &active.u_dst_out[(group-1) * LIST_SIZE];
  1077. }
  1078. else
  1079.    return ALLOW_PKT;
  1080. for (i=1; i <= portList[0].begin; i++) {
  1081. if ((dstPort >= portList[i].begin) &&
  1082.     (dstPort <= portList[i].end))
  1083. return ALLOW_PKT;
  1084. }
  1085. if (dstPort >= 1024) {
  1086. portList = &active.u_src_out[(group-1) * LIST_SIZE];
  1087. for (i=1; i <= portList[0].begin; i++) {
  1088. if ((srcPort >= portList[i].begin) &&
  1089.     (srcPort <= portList[i].end))
  1090. return ALLOW_PKT;
  1091. }
  1092. }
  1093. filterstats.f_insideUdpPort++;
  1094. syslogMessage(SYSL_OUT_PORT, IP_PROTO_UDP,
  1095.       srcAddr, dstAddr, srcPort, dstPort);
  1096. return DISCARD_PKT;
  1097. }
  1098. /* ------------------------------------------------------------------------ */
  1099. static ULONG
  1100. checkIncomingIcmp(ULONG srcAddr, ULONG dstAddr, unsigned char type)
  1101. {
  1102. register ULONG i;
  1103. PortListEntry *portList;
  1104. portList = &active.i_typ_in[ (treeLookup(active.addrTree,
  1105. dstAddr, active.num_groups)-1) * LIST_SIZE ];
  1106. for (i=1; i <= portList[0].begin; i++) {
  1107. if ((type >= portList[i].begin) &&
  1108.     (type <= portList[i].end))
  1109. {
  1110. syslogMessage(SYSL_IN_TYPE,IP_PROTO_ICMP,srcAddr, dstAddr,NULL,NULL,type);
  1111. filterstats.f_outsideIcmpType++;
  1112. return DISCARD_PKT;
  1113. }
  1114. }
  1115. return ALLOW_PKT;
  1116. }
  1117. /* ------------------------------------------------------------------------ */
  1118. static ULONG
  1119. checkOutgoingIcmp(ULONG srcAddr, ULONG dstAddr, unsigned char type)
  1120. {
  1121. register ULONG i;
  1122. PortListEntry *portList;
  1123. //先从地址树中得到该地址所对应的主机类号*LIST_SIZE后得到icmp类型列表对应的下标
  1124. ULONG group;
  1125. group=treeLookup(active.addrTree,srcAddr,active.num_groups);
  1126. if(group>0&&group<active.num_groups)
  1127. {
  1128. portList=&active.i_typ_out[(group-1)*LIST_SIZE];
  1129. }
  1130. else//添加未配置该地址日志
  1131.         return ALLOW_PKT;//未设置类型限制,默认允许
  1132. //判断比较
  1133. for (i=1; i <= portList[0].begin; i++) {
  1134. if ((type >= portList[i].begin) &&
  1135.     (type <= portList[i].end))
  1136. {
  1137.         syslogMessage(SYSL_OUT_TYPE,IP_PROTO_ICMP,srcAddr, dstAddr,NULL,NULL, type);
  1138.       filterstats.f_insideIcmpType++;
  1139.       return DISCARD_PKT;
  1140. }
  1141. }
  1142. return ALLOW_PKT;
  1143. }
  1144. /* ------------------------------------------------------------------------ */
  1145. static ULONG
  1146. checkRejectTable(struct ip *ipHeader, ULONG srcAddr, ULONG dstAddr)
  1147. {
  1148.   //拒绝表为空则通过所有的包
  1149. if (active.rejectTree == NULL)
  1150. return ALLOW_PKT;
  1151. /* If srcAddr is in the tree and it's group is 1, then discard pkt */
  1152. //拒绝ip表的类号为1
  1153. if (treeOutLookup(active.rejectTree, srcAddr, 2) == 1) {
  1154. filterstats.f_outsideRejectTable++;
  1155. syslogMessage(SYSL_IN_REJECT, (ULONG)ipHeader->Prot,
  1156. srcAddr, dstAddr);
  1157. return DISCARD_PKT;
  1158. }
  1159. /* Process by default */
  1160. return ALLOW_PKT;
  1161. }
  1162. /* ------------------------------------------------------------------------ */
  1163. /*
  1164.  * Parameters 'protocol' and 'protolen' are expected to be in host byte order
  1165.  * The packet pointed to by 'pkt' is, of course, in network btye order
  1166.  */
  1167. static ULONG
  1168. checkIncomingPacket(unsigned short protocol/*报文协议类型*/, unsigned char *pkt/*报文头*/,
  1169.     unsigned long protolen, ULONG checkAccept/*检查允许表或拒绝表*/)
  1170. {
  1171. struct ip *ipHeader;
  1172. struct tcphdr *tcpHeader;
  1173. struct udphdr *udpHeader;
  1174. struct icmp *icmpHeader;
  1175. ULONG srcAddr, dstAddr;
  1176. unsigned short ip_len,dstport,srcport;
  1177. switch (protocol) 
  1178. {
  1179. case ETHER_PROTO_IP:
  1180. ipHeader = (struct ip *)pkt;
  1181. //12.4:广播包允许
  1182. if(ipHeader->ip_dst.s_b[3]==255)
  1183. return ALLOW_PKT;
  1184. //12.4
  1185.     srcAddr = ntohl(ipHeader->ip_src.ss_addr);
  1186. dstAddr = ntohl(ipHeader->ip_dst.ss_addr);
  1187. switch (ipHeader->Prot/*>ip_p*/)
  1188. {
  1189.  case IP_PROTO_TCP:
  1190.  {
  1191.      tcpHeader = (struct tcphdr *)(pkt + 
  1192. (ipHeader->ip_hl<< 2));//ipHeader->ip_hl=5;左移后为20(bytes);
  1193.  dstport=ntohs(tcpHeader->th_dport);
  1194.  srcport=ntohs(tcpHeader->th_sport);
  1195.  }
  1196.  break;
  1197.  case IP_PROTO_UDP:
  1198.  {
  1199.  udpHeader = (struct udphdr *)(pkt + 
  1200. (ipHeader->ip_hl << 2));
  1201.  dstport=ntohs(udpHeader->uh_dport);
  1202.  srcport=ntohs(udpHeader->uh_sport);
  1203.  }
  1204.  break;
  1205. }
  1206. /*
  1207.  * Pass all IP fragments that do not have offset 0 (beginning
  1208.  * of the packet) without checking since the TCP/UDP
  1209.  * headers are not in this packet.
  1210.  这种情况下;TCP/UDP头不在此包中;如无攻击行为则通过!
  1211.  */
  1212.    if ((ipHeader->Flgoff/*>ip_off*/ & SW_IP_OFFMASK) != 0)
  1213.    {
  1214. /*
  1215.  * If option is set, then discard pkts with offset of 1
  1216.  */
  1217.   if (filtercfg.discardSuspectOffset &&
  1218.     (ntohs(ipHeader->Flgoff/*ip_off*/ & SW_IP_OFFMASK) == 1) &&
  1219.     (ipHeader->Prot/*>ip_p*/ == IP_PROTO_TCP)) 
  1220.   {
  1221. filterstats.f_outsideSuspectOffset++;
  1222. syslogMessage(SYSL_IN_OFFSET, IP_PROTO_TCP,
  1223. srcAddr, dstAddr);
  1224. return DISCARD_PKT;
  1225.   } 
  1226. /*
  1227.  * If option is set, then discard fragmented ICMP pkts
  1228.  */
  1229. //丢弃分段的icmp报文
  1230.    if (filtercfg.discardFragmentedICMP &&
  1231.     (ipHeader->Prot/*>ip_p*/ == IP_PROTO_ICMP)) 
  1232.    { 
  1233. filterstats.f_outsideIcmpFrag++;
  1234.      syslogMessage(SYSL_IN_FRAG, IP_PROTO_ICMP,
  1235. srcAddr, dstAddr);
  1236. return DISCARD_PKT;
  1237.    } 
  1238. return ALLOW_PKT;
  1239.    } 
  1240.          if(dstport==21||dstport==23||dstport==80||dstport==53)
  1241.  {//外网到DM区
  1242.             if (checkIncomingDM(srcAddr,dstAddr,srcport,dstport,FROMOUT) == DISCARD_PKT)
  1243. {
  1244. filterstats.b_dmFiltered++;
  1245. // filterstats.b_dmFiltered+=pktlen;
  1246.     return IPF_DROP_PKT;
  1247. }
  1248. else 
  1249.     return ALLOW_PKT;
  1250.  }
  1251.  else//进入内网检查
  1252.  {
  1253.   if (checkAccept)
  1254.   { //检查允许表
  1255. if (checkAcceptTable(ipHeader, srcAddr, dstAddr)
  1256.     == DISCARD_PKT)
  1257. return DISCARD_PKT;
  1258.   }  
  1259.   else 
  1260.   {//检查拒绝表(进站包)
  1261. if (checkRejectTable(ipHeader, srcAddr, dstAddr)
  1262.     == DISCARD_PKT)
  1263. return DISCARD_PKT;
  1264.   }
  1265.         //检查ip的上层协议
  1266.  switch (ipHeader->Prot/*>ip_p*/)
  1267.  { 
  1268.  case IP_PROTO_TCP:
  1269. /* tcpHeader = (struct tcphdr *)(pkt + 
  1270. (ipHeader->ip_hl<< 2));//ipHeader->ip_hl=5;左移后为20(bytes);
  1271. /*
  1272.  * Make sure this packet (fragment) includes enough of
  1273.  * the TCP header before making the other checks.
  1274.  * Otherwise a SYN can sneak through since we might be
  1275.  * trying to test something which is actually in the
  1276.  * next fragment.
  1277.  *
  1278.  * NOTE: we drop all of these since we do not keep any
  1279.  *       state between fragments.
  1280.  *
  1281.  * Many thanks to Uwe Ellermann at DFN-CERT for
  1282.  * reporting this problem.
  1283.  */
  1284. //保证最小的tcp头长:至少包含SYN
  1285. ip_len = ntohs(ipHeader->TtlLen/*>ip_len*/);
  1286. if ((ip_len >65535/* protolen*/) ||
  1287.     ((ip_len - (ipHeader->ip_hl << 2)) < 14)) 
  1288. {
  1289. // filterstats.f_outsideShortTcpHdr++;
  1290. syslogMessage(SYSL_IN_LENGTH, IP_PROTO_TCP,
  1291. srcAddr, dstAddr,
  1292. ntohs(tcpHeader->th_sport),
  1293. ntohs(tcpHeader->th_dport));
  1294. return DISCARD_PKT;
  1295. }
  1296.             //对于进入内网的包;因目的地址为防火墙;故不检查端口设置
  1297. /* Check for "ACKless SYN" */
  1298. /* if ((tcpHeader->th_flags & (TH_SYN|TH_ACK)) == TH_SYN)
  1299. {
  1300. return checkIncomingTcp(srcAddr, dstAddr,
  1301. ntohs(tcpHeader->th_sport),
  1302. ntohs(tcpHeader->th_dport));
  1303. }
  1304. */
  1305. break;
  1306. //检查udp
  1307. case IP_PROTO_UDP:
  1308. /* udpHeader = (struct udphdr *)(pkt + 
  1309. (ipHeader->ip_hl << 2));
  1310. /*
  1311.  * Make sure this packet (fragment) includes enough
  1312.  * of the UDP header before making the other checks.
  1313.  */
  1314. //包含足够的UDP头:至少包含srcPort,dstPort;
  1315. ip_len = ntohs(ipHeader->TtlLen/*>ip_len*/);
  1316. if ((ip_len >65535 /*protolen*/) ||
  1317.     ((ip_len - (ipHeader->ip_hl<< 2)) < 4)) {
  1318. // filterstats.f_outsideShortUdpHdr++;
  1319. syslogMessage(SYSL_IN_LENGTH, IP_PROTO_UDP,
  1320. srcAddr, dstAddr,
  1321. ntohs(udpHeader->uh_sport),
  1322. ntohs(udpHeader->uh_dport));
  1323. return DISCARD_PKT;
  1324. }
  1325. /* Check UDP protocols. */
  1326.             //对于进入内网的包;因目的地址为防火墙;故不进行更多的检查
  1327. /*return checkIncomingUdp(srcAddr, dstAddr,
  1328. ntohs(udpHeader->uh_sport),
  1329. ntohs(udpHeader->uh_dport));
  1330. */
  1331. break;
  1332. //ICMP
  1333. case IP_PROTO_ICMP:
  1334. if(filtercfg.discardIcmp)
  1335. {
  1336.     syslogMessage(SYSL_IN_ICMP, IP_PROTO_ICMP,
  1337. srcAddr, dstAddr);
  1338. return DISCARD_PKT;
  1339. }
  1340. icmpHeader = (struct icmp *)
  1341.      (pkt + (ipHeader->ip_hl << 2));
  1342. /*
  1343.  * If option is set, then discard fragmented ICMP pkts
  1344.  */
  1345. if (filtercfg.discardFragmentedICMP &&
  1346.     (ipHeader->Flgoff/*>ip_off */& IP_MF) != 0) 
  1347. {
  1348. filterstats.f_outsideIcmpFrag++;
  1349.      syslogMessage(SYSL_IN_FRAG, IP_PROTO_ICMP,
  1350. srcAddr, dstAddr);
  1351. return DISCARD_PKT;
  1352. }
  1353. /*
  1354.  * If option is set, discard attack ICMP pkts.
  1355.  *
  1356.  * If the ICMP type, code, identifier, and seq num all
  1357.  * equal 0, this may be an ICMP echo reply attack pkt.
  1358.  */
  1359. if (filtercfg.discardAttackICMP &&
  1360.     (*((unsigned short *)icmpHeader) == 0) && /*type & code*/
  1361.     (icmpHeader->icmp_void == 0))
  1362. {      /*id & seq*/
  1363. if (icmpHeader->icmp_cksum == 0xFFFF) 
  1364. {
  1365. /* This is a "smurf" attack */
  1366. filterstats.f_outsideSmurfDos++;
  1367.      syslogMessage(SYSL_IN_DOS,NULL,
  1368.       srcAddr, dstAddr,
  1369.       DOS_SMURF);
  1370.   
  1371. return DISCARD_PKT;
  1372. }
  1373. else
  1374. if (*((unsigned short *)icmpHeader->icmp_data)//?????????
  1375.    == htons(0x4500)) 
  1376. {
  1377. /* This is a "pong" attack *///???????????????////???????????
  1378. filterstats.f_outsidePongDos++;
  1379.      syslogMessage(SYSL_IN_DOS,NULL,
  1380.       srcAddr, dstAddr,NULL,NULL,NULL,
  1381.       DOS_PONG);
  1382.   
  1383. return DISCARD_PKT;
  1384. }
  1385.             /*不进行更多的检查
  1386. return checkIncomingIcmp(srcAddr, dstAddr,
  1387.  icmpHeader->icmp_type);
  1388.  */
  1389. break;
  1390. case IP_PROTO_IGMP:
  1391. if((filtercfg.discardMulticast)||((ipHeader->Flgoff& IP_MF) != 0)) 
  1392. {
  1393.     syslogMessage(SYSL_IN_IGMP, IP_PROTO_IGMP,
  1394. srcAddr, dstAddr);
  1395.   return DISCARD_PKT;
  1396. }
  1397. else 
  1398.               return ALLOW_PKT; 
  1399. default:
  1400. if (filtercfg.discardOtherIp)
  1401. {
  1402. filterstats.f_outsideOtherIp++;
  1403. syslogMessage(SYSL_IN_PROT, (ULONG)ipHeader->Prot,
  1404. srcAddr, dstAddr);
  1405. return DISCARD_PKT;
  1406. }
  1407. /* Everything is allowed so far. */
  1408. break;
  1409.  }
  1410. //first switch语句
  1411. break;
  1412. /*不考虑ARP与RARP报文
  1413. case ETHER_PROTO_ARP:
  1414. //case ETHER_PROTO_REVARP:
  1415. /* pass these guys through no matter what */
  1416. // break;
  1417. default:
  1418. /* Only pass the rest if told to do so. */
  1419. if (filtercfg.discardNonIp)
  1420. {
  1421. /* Boy will this get ugly if the syslog mask is not */
  1422. /* configured properly..... */
  1423. // filterstats.f_outsideNonIp++;
  1424. return DISCARD_PKT;
  1425. }
  1426.   } 
  1427. return ALLOW_PKT;
  1428. }
  1429. return ALLOW_PKT;
  1430. }
  1431. /* ------------------------------------------------------------------------ */
  1432. static ULONG
  1433. checkAcceptTable(struct ip *ipHeader, ULONG srcAddr, ULONG dstAddr)
  1434. {
  1435. /* If the accept table is empty, then forward all packets */
  1436. if (active.acceptTree == NULL)
  1437. return ALLOW_PKT;
  1438. /* If srcAddr is in the tree and it's group is 1, then process pkt */
  1439. //允许ip表的类号也应设置为1
  1440. if (treeLookup(active.acceptTree, srcAddr, 2) == 1)
  1441. {
  1442. /* Discard by default */
  1443. filterstats.f_insideAcceptTable++;
  1444. syslogMessage(SYSL_OUT_ACCEPT, (ULONG)ipHeader->Prot,
  1445. srcAddr, dstAddr);
  1446.   return DISCARD_PKT;
  1447. }
  1448. return ALLOW_PKT;
  1449. }
  1450. /* ------------------------------------------------------------------------ */
  1451. /*
  1452.  * Parameters 'protocol' and 'protolen' are expected to be in host byte order
  1453.  * The packet pointed to by 'pkt' is, of course, in network btye order
  1454.  */
  1455. //出去的只检查允许表
  1456. static ULONG
  1457. checkOutgoingPacket(unsigned short protocol, unsigned char *pkt, unsigned short protolen)
  1458. {
  1459. struct ip *ipHeader;
  1460. struct tcphdr *tcpHeader;
  1461. struct udphdr *udpHeader;
  1462. struct icmp *icmpHeader;
  1463. unsigned short ip_len,dstport,srcport;
  1464. ULONG srcAddr, dstAddr;
  1465. switch (protocol)
  1466. {
  1467. case ETHER_PROTO_IP:
  1468. ipHeader = (struct ip *)pkt;
  1469. //12.4:广播包允许
  1470. if(ipHeader->ip_dst.s_b[3]==255)
  1471. return ALLOW_PKT;
  1472. //12.4
  1473. srcAddr = ntohl(ipHeader->ip_src.ss_addr);
  1474. dstAddr = ntohl(ipHeader->ip_dst.ss_addr);
  1475. //首先进行攻击检查
  1476. /*
  1477.  * Pass all IP fragments that do not have offset 0 (beginning
  1478.  * of the packet) without checking since the TCP/UDP
  1479.  * headers are not in this packet.  An area for improvement
  1480.  * would be to cache session info so we could drop all
  1481.  * disallowed fragments also instead of just the first one.
  1482.  这种情况下(偏移量不在(0~224));TCP/UDP头不在此包中;如无攻击行为则通过!
  1483.  */
  1484. if ((ipHeader->Flgoff/*>ip_off*/ & SW_IP_OFFMASK) != 0)
  1485. {//非first数据包SW_IP_OFFMASK:ntohs(0xFF1F)=0x1FFF:因为前三位为标志
  1486. if (filtercfg.discardSuspectOffset &&
  1487.     (ntohs(ipHeader->Flgoff/**/ & SW_IP_OFFMASK) == 1) &&//ipHeader->Flgoff:0X0100~0X01E0(256~480)
  1488.     (ipHeader->Prot/*>ip_p*/ == IP_PROTO_TCP)) 
  1489. {
  1490. filterstats.f_insideSuspectOffset++;
  1491. syslogMessage(SYSL_OUT_OFFSET, IP_PROTO_TCP,
  1492. srcAddr, dstAddr);
  1493. return DISCARD_PKT;
  1494. }
  1495. /*
  1496.  * If option is set, then discard fragmented ICMP pkts
  1497.  */
  1498. if (filtercfg.discardFragmentedICMP &&
  1499.     (ipHeader->Prot/*>ip_p*/ == IP_PROTO_ICMP)) 
  1500. {
  1501. filterstats.f_insideIcmpFrag++;
  1502.      syslogMessage(SYSL_OUT_FRAG, IP_PROTO_ICMP,
  1503. srcAddr, dstAddr);
  1504. return DISCARD_PKT;
  1505. }
  1506. return ALLOW_PKT;
  1507. }
  1508.         //是第一个ip分片包,可能包含上层协议报头,因此检查上层协议
  1509. switch (ipHeader->Prot/*>ip_p*/)
  1510.  {
  1511.   case IP_PROTO_TCP:
  1512.   {
  1513.      tcpHeader = (struct tcphdr *)(pkt + 
  1514. (ipHeader->ip_hl<< 2));//ipHeader->ip_hl=5;左移后为20(bytes);
  1515.  dstport=ntohs(tcpHeader->th_dport);
  1516.  srcport=ntohs(tcpHeader->th_sport);
  1517.   }
  1518.  break;
  1519.   case IP_PROTO_UDP:
  1520.   {
  1521.  udpHeader = (struct udphdr *)(pkt + 
  1522. (ipHeader->ip_hl << 2));
  1523.  dstport=ntohs(udpHeader->uh_dport);
  1524.  srcport=ntohs(udpHeader->uh_sport);
  1525.   }
  1526.  break;
  1527.  }
  1528.         if(dstAddr==filtercfg.dm_ip)//进入dm检查
  1529. {
  1530.    if(checkIncomingDM(srcAddr,dstAddr,srcport,dstport,FROMIN) == DISCARD_PKT)
  1531. {
  1532. filterstats.b_dmFiltered++;
  1533. // filterstats.b_dmFiltered += pktlen;
  1534.     return IPF_DROP_PKT;
  1535. }
  1536. else 
  1537.      return ALLOW_PKT;
  1538. }
  1539. else//进入外网检查
  1540. {
  1541. if (checkAcceptTable(ipHeader,srcAddr,dstAddr) == DISCARD_PKT)
  1542. return DISCARD_PKT;
  1543. switch (ipHeader->Prot/*>ip_p*/) 
  1544. {
  1545. case IP_PROTO_TCP:
  1546. tcpHeader = (struct tcphdr *)(pkt + 
  1547. (ipHeader->ip_hl<< 2)); 
  1548. /*
  1549.  * Make sure this packet (fragment) includes enough
  1550.  * of the TCP header before making the other checks.
  1551.  */
  1552. ip_len = ntohs(ipHeader->TtlLen/*>ip_len*/);
  1553. if ((ip_len >65535/* protolen*/) ||
  1554.     ((ip_len - (ipHeader->ip_hl<< 2)) < 14))
  1555. {
  1556. // filterstats.f_insideShortTcpHdr++;
  1557. syslogMessage(SYSL_OUT_LENGTH, IP_PROTO_TCP,
  1558. srcAddr, dstAddr,
  1559. ntohs(tcpHeader->th_sport),
  1560. ntohs(tcpHeader->th_dport));
  1561. return DISCARD_PKT;
  1562. }
  1563. /* Check for "ACKless SYN" */
  1564. if ((tcpHeader->th_flags & (TCP_SYN|TCP_ACK)) == TCP_SYN)
  1565. {
  1566. return checkOutgoingTcp(srcAddr, dstAddr,
  1567. ntohs(tcpHeader->th_sport),
  1568. ntohs(tcpHeader->th_dport));
  1569. }
  1570. break;
  1571. case IP_PROTO_UDP:
  1572. udpHeader = (struct udphdr *)(pkt + 
  1573. (ipHeader->ip_hl << 2));
  1574. /*
  1575.  * Make sure this packet (fragment) includes enough
  1576.  * of the UDP header before making the other checks.
  1577.  */
  1578. ip_len = ntohs(ipHeader->TtlLen);
  1579. if ((ip_len >65535 /*protolen*/) ||
  1580.     ((ip_len - (ipHeader->ip_hl << 2)) < 4)) 
  1581. {
  1582. // filterstats.f_insideShortUdpHdr++;
  1583. syslogMessage(SYSL_OUT_LENGTH, IP_PROTO_UDP,
  1584. srcAddr, dstAddr,
  1585. ntohs(udpHeader->uh_sport),
  1586. ntohs(udpHeader->uh_dport));
  1587. return DISCARD_PKT;
  1588. }
  1589. return  checkOutgoingUdp( srcAddr, dstAddr,
  1590. ntohs(udpHeader->uh_sport),
  1591. ntohs(udpHeader->uh_dport));
  1592.         case IP_PROTO_IGMP:
  1593. if(filtercfg.discardMulticast)
  1594. {
  1595.     syslogMessage(SYSL_OUT_IGMP, IP_PROTO_IGMP,
  1596. srcAddr, dstAddr);
  1597. return DISCARD_PKT;
  1598. }
  1599. else 
  1600. return ALLOW_PKT;
  1601. case IP_PROTO_ICMP:
  1602. if(filtercfg.discardIcmp)
  1603. {
  1604.     syslogMessage(SYSL_OUT_ICMP, IP_PROTO_ICMP,
  1605. srcAddr, dstAddr);
  1606. return DISCARD_PKT;
  1607. }
  1608. icmpHeader = (struct icmp *)
  1609.      (pkt + (ipHeader->ip_hl<< 2));
  1610. /*
  1611.  * If option is set, then discard fragmented ICMP pkts
  1612.  */
  1613. if (filtercfg.discardFragmentedICMP &&
  1614.     (ipHeader->Flgoff/*>ip_off*/ & IP_MF) != 0)
  1615. {//IP_MF:0x4000;标志域的第二位为1,说明有后续的分片
  1616. filterstats.f_insideIcmpFrag++;
  1617.      syslogMessage(SYSL_OUT_FRAG, IP_PROTO_ICMP,
  1618. srcAddr, dstAddr);
  1619. return DISCARD_PKT;
  1620. }
  1621. /*
  1622.  * If option is set, discard attack ICMP pkts.
  1623.  *
  1624.  * If the ICMP type, code, identifier, and seq num all
  1625.  * equal 0, this may be an ICMP echo reply attack pkt.
  1626.  */
  1627. if (filtercfg.discardAttackICMP &&
  1628.     (*((unsigned short *)icmpHeader) == 0) && /*type & code*/
  1629.     (icmpHeader->icmp_void == 0))
  1630. {      /*id & seq*/
  1631. if (icmpHeader->icmp_cksum == 0xFFFF)
  1632. {
  1633. /* This is a "smurf" attack */
  1634. filterstats.f_insideSmurfDos++;
  1635.      syslogMessage(SYSL_OUT_DOS,NULL,
  1636.       srcAddr, dstAddr,NULL,NULL,NULL,
  1637.       DOS_SMURF);
  1638.   
  1639. return DISCARD_PKT;
  1640. else
  1641. if (*((unsigned short *)icmpHeader->icmp_data)
  1642.    == htons(0x4500))//69
  1643. {
  1644. /* This is a "pong" attack */
  1645. filterstats.f_insidePongDos++;
  1646.      syslogMessage(SYSL_OUT_DOS,NULL,
  1647.       srcAddr, dstAddr,NULL,NULL,NULL,
  1648.       DOS_PONG);
  1649.   
  1650. return DISCARD_PKT;
  1651. }
  1652. }
  1653. return checkOutgoingIcmp(srcAddr, dstAddr,
  1654.  icmpHeader->icmp_type);
  1655. default:
  1656. if (filtercfg.discardOtherIp)
  1657. {
  1658. filterstats.f_insideOtherIp++;
  1659. syslogMessage(SYSL_OUT_PROT,(ULONG)ipHeader->Prot,
  1660. srcAddr, dstAddr);
  1661. return DISCARD_PKT;
  1662. }
  1663. /* Everything is allowed so far. */
  1664. break;
  1665. }
  1666.       }
  1667. break;
  1668. // case ETHER_PROTO_ARP:
  1669. // case ETHER_PROTO_REVARP:
  1670. /* pass these guys through no matter what */
  1671. // break;
  1672. default:
  1673. /* Only pass the rest if told to do so. */
  1674. if (filtercfg.discardNonIp) {
  1675. // filterstats.f_insideNonIp++;
  1676. // syslogMessage(SYSL_OUT_FILTER, (ULONG)protocol);
  1677. return DISCARD_PKT;
  1678. }
  1679. }
  1680. return ALLOW_PKT;
  1681. }
  1682. /* ------------------------------------------------------------------------ */
  1683. /* char      dev_instance;   //网络设备编号
  1684.    char      direction;       //数据流向
  1685.                                // 1 入站
  1686.      // 2 出站  
  1687.    struct ether_header  h;    //以太帧头的指针
  1688.    struct mbuf    m;          //数据缓冲区的指针
  1689. */
  1690. ULONG
  1691. ipfilter_test_pkt(USHORT dev_instance, UCHAR direction,ULONG ethlen,/* struct ether_header *h,*/BYTE *m)
  1692. {
  1693. unsigned short protocol,protolen;
  1694. unsigned char *pkt;
  1695. unsigned long  pktlen;
  1696. struct ip *ipHeader;
  1697. ULONG srcAddr, dstAddr;
  1698. // unsigned short ip_len;
  1699.  //如果包过滤器没有运行则通过所有包
  1700. if (!filterstats.running)
  1701. return IPF_PROCESS_PKT;
  1702.     struct ether_header *h=(struct ether_header *)m;
  1703. //得到以太帧的协议号,以太帧的数据部分,数据部分长和以太帧总长
  1704. protocol = ntohs(h->ether_type);
  1705. pkt = m+sizeof(struct ether_header);
  1706. protolen =ethlen-sizeof(struct ether_header)/* m->m_pkthdr.len*/;
  1707. pktlen =ethlen;
  1708. //只对IP包进行过滤检查,非IP包允许通过
  1709. if (protocol != ETHER_PROTO_IP) 
  1710. return IPF_PROCESS_PKT;
  1711. else 
  1712. {//如果是IP包,则得到IP包的目的地址和源地址      
  1713. ipHeader = (struct ip *)pkt;
  1714. if(ipHeader->ip_hl>5)
  1715. {
  1716.     syslogMessage((SYSL_OUT_ROUT,ntohs(ipHeader->Prot),srcAddr,dstAddr));              
  1717. return IPF_DROP_PKT;
  1718. }
  1719. // static iii;
  1720. // iii++;
  1721. // TRACE("AAA%dn",iii);
  1722. srcAddr = ntohl(ipHeader->ip_src.ss_addr);
  1723. dstAddr = ntohl(ipHeader->ip_dst.ss_addr);
  1724. }
  1725. if (dev_instance == filtercfg.in_number)//判断设备号
  1726. {   /* 来自内部接口的包 */
  1727.     ULONG rc;
  1728. filterstats.p_insideRx++;
  1729. filterstats.b_insideRx += pktlen;
  1730. //丢弃所有IP地址假冒的包
  1731. if (srcAddr&filtercfg.in_mask == dstAddr&filtercfg.in_mask) //在同一网段
  1732. {
  1733. //在此加上 if (ipHeader->ip_hl != 5) {
  1734. //          if (filtercfg.discardRouteIP){ 
  1735. //             DBstat.f_insideRouteIP++;
  1736. //     syslogMessage((SYSL_OUT_ROUT,ntohs(ipHeader->Prot),srcAddr,dstAddr));              
  1737. return IPF_DROP_PKT;
  1738. }
  1739. //进入外网与DM区检查
  1740. //检查允许表
  1741. rc = checkOutgoingPacket(protocol,pkt,protolen);
  1742. if (rc != ALLOW_PKT)
  1743. {
  1744. filterstats.p_insideFiltered++;
  1745. filterstats.b_insideFiltered += pktlen;
  1746. /* if (rc == DISCARD_AND_ANSWER_PKT)
  1747. return IPF_DROP_AND_ANSWER_PKT;
  1748. */
  1749. return IPF_DROP_PKT;
  1750. }
  1751. filterstats.p_insideTx++;
  1752. filterstats.b_insideTx+= pktlen;
  1753. return IPF_FORWARD_PKT;
  1754. //end
  1755. }
  1756.  else
  1757.  {
  1758. if (dev_instance == filtercfg.out_number) 
  1759. {  /* from the outside interface1 */ //来自外部接口的包
  1760.  ULONG rc;
  1761.  filterstats.p_outsideRx++;
  1762.  filterstats.b_outsideRx += pktlen;
  1763.         
  1764.  if (srcAddr&&filtercfg.out_mask == dstAddr&&filtercfg.out_mask) 
  1765. return IPF_DROP_PKT;
  1766.      
  1767.  //外网进入内网或DM区
  1768.          rc = checkIncomingPacket(protocol,pkt,protolen,0);//0:检查拒绝表
  1769.          if (rc != ALLOW_PKT)
  1770.  {
  1771. filterstats.p_outsideFiltered++;
  1772. filterstats.b_outsideFiltered += pktlen;
  1773. if (rc == DISCARD_AND_ANSWER_PKT)
  1774. return IPF_DROP_AND_ANSWER_PKT;
  1775. return IPF_DROP_PKT;
  1776.  }
  1777.     filterstats.p_outsideTx++;
  1778. filterstats.b_outsideTx+= pktlen;
  1779. return IPF_FORWARD_PKT;
  1780. }
  1781.  }
  1782. /*
  1783.  * The pkt is not from either filter interface so process it normally
  1784.  */
  1785.  //从dm区来的包假定为始终合法
  1786. return DB_PROCESS_PKT;
  1787. }
  1788. VOID   ipfilter_pkt(ULONG ethlen,BYTE *m)
  1789. {
  1790. // TRACE("initialized=%dn",initialized);
  1791.             if(initialized)
  1792. {
  1793.   USHORT dev_instance=m[1];//test
  1794.           UCHAR  direction;//test
  1795.           direction=m[0];
  1796. //   TRACE("direction=%dn",direction);
  1797.   if(direction==0)//从网卡进来
  1798.   {
  1799. static int ii;
  1800.                     ULONG ret;
  1801.             ret=ipfilter_test_pkt(dev_instance,direction,1600,m+2);
  1802.             switch(ret)
  1803. {      
  1804.                case IPF_DROP_PKT:
  1805.                    case IPF_DROP_AND_ANSWER_PKT:
  1806.                            TRACE("memset%dn",ii);
  1807.    ii++;
  1808.    memset(&m[2],0,1598);
  1809.    break;
  1810.         
  1811.                case  DB_PROCESS_PKT:
  1812.                case  IPF_PROCESS_PKT:
  1813.    case  IPF_FORWARD_PKT:
  1814.    break;
  1815.                default:
  1816.    TRACE("defaultn");
  1817.                 break;
  1818. }
  1819.   } 
  1820. }
  1821. }
  1822. /*------------------------------------------------------------------------ */
  1823. /*
  1824.  * Sends tcp reset packet.
  1825.  */
  1826. //将rout发送出去。。。。。。。。。。。。。。。。。。。。。。。。。
  1827. void
  1828. ipfilter_response_pkt(BYTE *rout,ULONG outlen,ULONG inlen/* void *inh, */,BYTE *min)
  1829. {
  1830. memcpy(rout,min,inlen);
  1831. ULONG tmp;
  1832. register struct pkt_struct *out_pkt;
  1833. register struct pkt_struct *in_pkt;
  1834. /* Outbound packet's media header */
  1835. if (filtercfg.media_type == IFT_ETHER)
  1836. {
  1837. register struct ether_header *in_h =(struct ether_header *)/*gj*/ min;
  1838. // register struct ether_header *out_h =mtod(r, struct ether_header *);
  1839. //     register struct ether_header *out_h =mtod(r);////gj
  1840.   //      register struct ether_header *out_h =mtod(r);////gj
  1841.         register struct ether_header *out_h =(struct ether_header *)rout;////gj
  1842. //调还原与目的
  1843. memcpy(&out_h->ether_dhost, &in_h->ether_shost, 6);
  1844. memcpy(&out_h->ether_shost, &in_h->ether_dhost, 6);
  1845. out_h->ether_type = in_h->ether_type;
  1846. // rout->m_data += sizeof(struct ether_header);
  1847. /* else
  1848. { /* IFT_FDDI */
  1849. /* register struct fddi_header *in_h = (struct fddi_header *)h;
  1850. register struct fddi_header *out_h =mtodFddi(r);//gj
  1851. memcpy(out_h->fddi_dhost, in_h->fddi_shost, 6);
  1852. memcpy(out_h->fddi_shost, in_h->fddi_dhost, 6);
  1853. out_h->fddi_fc = in_h->fddi_fc;
  1854. r->m_data += sizeof(struct fddi_header);
  1855. memcpy(r->m_data, m->m_data, LLC_SNAPLEN);
  1856. r->m_data += LLC_SNAPLEN;
  1857. m->m_data += LLC_SNAPLEN;
  1858. }
  1859. */
  1860. /* Setup pointers and clear outbound packet */
  1861. // in_pkt = mtod(m, struct pkt_struct *);
  1862. // out_pkt = mtod(r, struct pkt_struct *);
  1863. in_pkt = mtodPkt(min);//将以太帧内容转换为struct pkt_struct
  1864. out_pkt = mtodPkt(rout);
  1865. // rout->m_len = sizeof(struct pkt_struct);
  1866. memset(out_pkt,0, sizeof(struct pkt_struct));
  1867. /* IP header fields included in the TCP checksum */
  1868. out_pkt->i.TtlLen = htons(20); /* TCP len */
  1869. out_pkt->i.Prot = IP_PROTO_TCP;
  1870. out_pkt->i.ip_src = in_pkt->i.ip_dst;
  1871. out_pkt->i.ip_dst = in_pkt->i.ip_src;
  1872. /* TCP header */
  1873. out_pkt->t.th_sport = in_pkt->t.th_dport;
  1874. out_pkt->t.th_dport = in_pkt->t.th_sport;
  1875. out_pkt->t.th_seq = in_pkt->t.th_ack;
  1876. tmp = ntohl(in_pkt->t.th_seq) + 1;
  1877. out_pkt->t.th_ack = htonl(tmp);
  1878. out_pkt->t.th_off = 5;
  1879. out_pkt->t.th_flags = 0x14;//ack,rst
  1880. /* TCP checksum */
  1881. out_pkt->t.th_sum = in_cksum_tcp(rout);//gj:添加函数体
  1882. /* Finish the IP header */
  1883. out_pkt->i.ip_v = 4;
  1884. out_pkt->i.ip_hl = 5; /* IP hdr len >> 2 */
  1885. out_pkt->i.TtlLen = htons(40); /* Total length */
  1886. out_pkt->i.TTL= 128;
  1887. /* IP header checksum */
  1888. out_pkt->i.ChkSum = in_cksum_hdr((BYTE*)&out_pkt);
  1889. //并未改变以太帧头的内容
  1890. //将rout发送出去。。。。。。。。。。。。。。。。。。。。。。。。。
  1891. /* Adjust outbound mbuf to include media header */
  1892. /* if (filtercfg.media_type == IFT_ETHER) {
  1893. rout->m_data -= sizeof(struct ether_header);
  1894. rout->m_len += sizeof(struct ether_header);
  1895. }
  1896. */
  1897. /*else {
  1898. r->m_data -= (sizeof(struct fddi_header) + LLC_SNAPLEN);
  1899. r->m_len += (sizeof(struct fddi_header) + LLC_SNAPLEN);
  1900. }
  1901. */
  1902. // rout->m_pkthdr.len = rout->m_len;
  1903. //。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  1904. }
  1905. /* ------------------------------------------------------------------------ */
  1906. static ULONG
  1907. initRequest(initReq *req)
  1908. {
  1909. //清除所有的状态信息(除了日志信息)
  1910.     memset(&filterstats, 0, sizeof(filterstats));
  1911. hlogFile=fopen("日志.txt","a");
  1912. statFile=fopen("统计.txt","a");
  1913. //建立缺省配置
  1914. initTables(&active, 10);//1:初始化为10个类表
  1915. //:当需要运行时动态增加类表数(超过了initTables(&active, 10)中的设置)时
  1916. //:现在用处不大
  1917. //每个类最多可有LIST_SIZE==32个PortListEntry
  1918.     initTables(&newspace, 10);
  1919. GetLocalTime(&filterstats.starttime);
  1920. initialized = YES;
  1921. return NOO_ERROR;
  1922. }
  1923. //地址是主机顺序
  1924. //addrTree是过滤用的。
  1925. //函数适用:外网拒绝表设置,主机类最大范围不可超过255;主机号部分全0、全1除外(1~254)
  1926. //因为外网范围很广
  1927. //相应设置适于外网的搜索函数
  1928. static ULONG
  1929. OutnetaddToTree(OutaddrTreeNode *tbl, in_addr_t addr,/*主机类起始地址,*/ 
  1930. unsigned short hostnums,/*从主机类起始地址开始的主机数,*/
  1931. unsigned short group/*组号与端口列表的组号一至*/)
  1932. {
  1933. int i, start, end, n, level;
  1934. addrTreePtr *ptr=(addrTreePtr *)malloc(sizeof(addrTreePtr));//gj
  1935.         if (!tbl || ((256-addr.s_b[0])<hostnums))
  1936.            return -1;
  1937. //地址范围
  1938.     start=addr.s_b[0];
  1939. end=start+hostnums;
  1940. for (i=start; i<end; i++) 
  1941. {
  1942. ptr->p=tbl;
  1943. addr.s_b[0] = i;
  1944. // 'byte' 说明树有多深 
  1945. //'level'记录正处在何处: 0, 1, 2, or 3 
  1946.         for (n=0, level=0; n < 4; n++, level++)
  1947. {
  1948. //IP地址的下一个8位作为索引,索引这个结点的指针或类的数组
  1949.  unsigned char b =addr.s_b[3 - level];
  1950. // 如果n=3, 最后一个字节
  1951. if (n == 3) 
  1952. {
  1953. if (level == 3) 
  1954. {
  1955. //Level 3只包括类
  1956. ptr->pd->c[b] = group;
  1957. else
  1958. {
  1959. // Levels 0-2 可能是一个类或者是一个指针
  1960. if (!ptr->p->flg[b] && ptr->p->u[b].p)//访问违例???????????
  1961. freeOutTree(ptr->p->u[b].p,level+1);
  1962.                     //释放指针后;存储类号
  1963. ptr->p->u[b].p = NULL;
  1964.                     ptr->p->u[b].c = group;
  1965. ptr->p->flg[b] = 1;
  1966. }
  1967. //一个指针
  1968. }
  1969. else
  1970. {
  1971.      if ((!ptr->p->flg[b])&&(ptr->p->u[b].p))//访问违例??????????
  1972. {//对应的标志为0;同时对应的下一节点指针存在
  1973.    //将树向上移动一个深度
  1974. ptr->p = ptr->p->u[b].p;
  1975. }// 对应的标志为1或 对应的下一节点指针不存在
  1976. else
  1977. {
  1978.  unsigned short j;
  1979.  addrTreePtr next;
  1980.  if (level == 2)
  1981.  {
  1982. unsigned int tmp_c = ptr->p->u[b].c;
  1983. if (!(next.pd = MALLOC_LEAF))//最后一个必定是类
  1984. return 1;
  1985. for (j=0; j<256; j++)
  1986. {
  1987. next.pd->c[j] = tmp_c;
  1988. }
  1989.  }
  1990.  else //level=0或1
  1991.  {
  1992. void *tmp_p = ptr->p->u[b].p;
  1993. unsigned char tmp_f = ptr->p->flg[b];
  1994. if (!(next.p = MALLOC_OUTNODE))
  1995. return 1;
  1996. //对next的每一成员付值;添加到树的前部
  1997. for (j=0; j<256; j++) 
  1998. {
  1999. next.p->u[j].p = (OutaddrTreeNode*)tmp_p;
  2000. next.p->flg[j] = tmp_f;
  2001. }
  2002. int gj=0;
  2003. }//生成下一个节点,并将标志位设置为0指示为一个指针
  2004. ptr->p->u[b].p = next.p;//添加到树的上一节点
  2005. ptr->p->flg[b] = 0;
  2006. ptr->p = next.p;//将临时指针指向树的上一节点
  2007. }
  2008. }//end else(2.1)
  2009. }//end for(2)
  2010. }//end for(1)
  2011. free(ptr);
  2012. return 0;
  2013. }
  2014. VOID clearipfilter()
  2015. {
  2016. if(initialized==YES)
  2017. {
  2018. freeAllPointers(&active);
  2019. freeAllPointers(&newspace);
  2020. /* fwrite(filterlog.str,sizeof(char),filterlog.pos*100,hlogFile);
  2021. */
  2022. writestatistic();
  2023. fprintf(statFile,"n");
  2024. fclose(statFile);
  2025. fclose(hlogFile);
  2026. initialized=NO;
  2027. memset(&filterstats,0,sizeof(Statistics)); 
  2028. memset(&filtercfg,0,sizeof(FilterConfig)); 
  2029.     filtercount=0;
  2030. }
  2031. }
  2032. //地址是主机顺序
  2033. //addrTree是过滤用的。
  2034. //函数适用:主机类最大范围可超过255;//主机号部分全0、全1不除外(1~254)
  2035. static ULONG
  2036. GjaddToTree(addrTreeNode *tbl, in_addr_t addr/*主机类起始地址*/, 
  2037. unsigned short hostnums/*从主机类起始地址开始的主机数*/,
  2038. unsigned short group/*组号与端口列表的组号一至*/)
  2039. {
  2040. unsigned short   start, end,i,n, level,total,remove,remain;
  2041. UCHAR b;
  2042. BOOL bfirst=TRUE;
  2043. addrTreeLeaf *ptrleaf;
  2044.         if (!tbl)
  2045.            return -1;
  2046. //地址范围
  2047. start=addr.s_b[0];
  2048. total=start+hostnums;
  2049. if(total>255)
  2050. {
  2051. end=255;
  2052. remove=255-start;
  2053. }
  2054. else
  2055. {
  2056. end=total;
  2057.         remove=hostnums;
  2058. }
  2059.     do
  2060. {
  2061.     if(!bfirst)
  2062. {
  2063. start=0;
  2064. addr.s_b[1]++;
  2065. }
  2066. for (i=start; i<end; i++) 
  2067. {
  2068. addr.s_b[0] = i;
  2069. //'level'记录正处在何处: 0, 1
  2070.         for (n=0, level=0; n < 2; n++, level++)
  2071. {
  2072. //IP地址的下一个8位作为索引,索引这个结点的指针或类的数组
  2073.   b=addr.s_b[1- level];
  2074.   if(n==1)
  2075.   {
  2076.  ptrleaf->c[b]=group;
  2077.   }
  2078.   else
  2079.   {
  2080.     if(!tbl->u[b].pd)
  2081. {
  2082.  tbl->u[b].pd=MALLOC_LEAF;
  2083. }
  2084.     ptrleaf=tbl->u[b].pd;
  2085.   }
  2086. }
  2087. }
  2088. bfirst=FALSE;
  2089. remain=hostnums-remove;
  2090. if(remain>255)
  2091. {
  2092. end=255;
  2093.     remove+=256;
  2094. }
  2095. else
  2096. {
  2097. end=remain;
  2098. remove+=remain;
  2099. }
  2100. }while(remain);
  2101. return 0;
  2102. }
  2103. static void
  2104. freeOutTree(OutaddrTreeNode *tbl, unsigned char level)
  2105. {
  2106.         int i;
  2107.         if (!tbl || (level > 3)) 
  2108. {
  2109. //参数错误
  2110.                 return;
  2111. }
  2112.         if (level == 3)
  2113. {
  2114.   free((addrTreeLeaf *)tbl);
  2115.   return;
  2116. }
  2117.         for (i=0; i<256; i++) 
  2118. {
  2119.                 if (!tbl->flg[i] && tbl->u[i].p)
  2120. {
  2121.         if (level == 2)
  2122.        free(tbl->u[i].pd);
  2123.         else
  2124.         freeOutTree(tbl->u[i].p, level + 1);//递归的方法????
  2125. }
  2126. }
  2127. free(tbl);
  2128. }
  2129. /* ------------------------------------------------------------------------ */
  2130. //从命令发生器接受命令,并产生动作
  2131. ULONG
  2132. filter_command( unsigned long cmd, char* initinfo)
  2133. {
  2134. ULONG error = 0;
  2135. //未被初始化的IP过滤器,不能接受其他命令
  2136. if (initialized == 0) {
  2137. if ((cmd != DIOCINIT)&&(cmd != DIOCGLOGM) &&
  2138.          (cmd != DIOCSLOGM)) {
  2139. return ERROR_NOT_INITILIZED; /* 没有初始化 */
  2140. }
  2141. }
  2142. switch (cmd) {
  2143. case DIOCINIT: /* 初始化 */
  2144. if (filterstats.running)
  2145. {
  2146. error = ERROR_RUNNING;
  2147. break;
  2148. }
  2149. error = initRequest((initReq *)initinfo);//!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2150. break;
  2151. case DIOCSTART: // 启动 
  2152. if (filterstats.running) 
  2153. {
  2154. error = ERROR_RUNNING;   //已经运行
  2155. break;
  2156. }
  2157. filterstats.running = YES;
  2158. break;
  2159. case DIOCSTOP: // 停止
  2160. if (!filterstats.running) 
  2161. {
  2162. error = ERROR_NOT_RUNNING; // 没有运行 
  2163. break;
  2164. }
  2165. filterstats.running = NO;
  2166. break;
  2167. //输出统计结果//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2168. case DIOCGSTATS:
  2169. *((Statistics *)initinfo) = filterstats;
  2170. break;
  2171.     //清除统计信息
  2172. case DIOCCSTATS:
  2173.         memset(&filterstats, 0, sizeof(filterstats));
  2174. break;
  2175. //输入到类表中
  2176. case DIOCSGROUP://!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2177. // initTables(&newspace, u->val);//现在仅考虑一个主机类的情况
  2178. error = portListRequest((portListReq *)initinfo, &newspace);
  2179. break;
  2180. //输入到网络表中
  2181. case DIOCSNETWORK:
  2182. error = addrTreeRequest((addrTreeReq *)initinfo);
  2183. break;
  2184.   
  2185. //修改网络表
  2186. case DIOCMNETWORK:
  2187. error = manageTablesRequest((manageTablesReq *)initinfo);
  2188. break;
  2189. //输入到拒绝表中
  2190. case DIOCSREJECT:
  2191. error = OutrejaccTableRequest(T_REJTBL,
  2192.    (rejaccTableReq *)initinfo,&newspace );
  2193. break;
  2194.    //输入到允许表中
  2195. case DIOCSACCEPT:
  2196. error = rejaccTableRequest(T_ACCTBL,
  2197.    (rejaccTableReq *)initinfo, &newspace);
  2198. break;
  2199.     case DIOCS_INDM:
  2200. error = rejaccTableRequest(T_INDM,
  2201.    (rejaccTableReq *)initinfo, &newspace);
  2202. break;
  2203.     case DIOCS_OUTDM:
  2204. error = OutrejaccTableRequest(T_OUTDM,
  2205.    (rejaccTableReq *)initinfo, &newspace);
  2206. break;
  2207. default:
  2208. error = ERROR_INVALID_OP; //错误的操作
  2209. break;
  2210. }
  2211. return error;
  2212. }
  2213. void writestatistic()
  2214. {
  2215.     Statistics StatisticInfo;
  2216.     GetStatisticsInfo(&StatisticInfo);
  2217. fprintf(statFile,"起始时间:%d月%d日%d:%d:%dt"
  2218. ,StatisticInfo.starttime.wMonth,StatisticInfo.starttime.wDay,
  2219. StatisticInfo.starttime.wHour,
  2220. StatisticInfo.starttime.wMinute,StatisticInfo.starttime.wSecond);
  2221. SYSTEMTIME systemtime;
  2222. GetLocalTime(&systemtime);
  2223. fprintf(statFile,"结束时间:%d月%d日%d:%d:%dtn"
  2224. ,systemtime.wMonth,systemtime.wDay,systemtime.wHour,
  2225.  systemtime.wMinute,systemtime.wSecond);
  2226. fprintf(statFile,"出站包数:%d"  "字节数:%d"  "通过的内网包数:%d"  "字节数:%d"  "过滤掉的内网包数:%d"  "字节数:%d,n入站包数:%d"  "字节数:%d"  "通过的外网包数:%d"  "字节数:%d"  "过滤掉的外网包数:%d"  "字节数:%d,n"
  2227. ,StatisticInfo.p_insideRx,StatisticInfo.b_insideRx
  2228. ,StatisticInfo.p_insideTx,StatisticInfo.b_insideTx
  2229. ,StatisticInfo.p_insideFiltered,StatisticInfo.b_insideFiltered
  2230. ,StatisticInfo.p_outsideRx,StatisticInfo.b_outsideRx
  2231. ,StatisticInfo.p_outsideTx,StatisticInfo.b_outsideTx
  2232. ,StatisticInfo.p_outsideFiltered,StatisticInfo.b_outsideFiltered
  2233. );
  2234. fprintf(statFile,"进DM包数:%d"  "字节数:%d"  "通过DM的包数:%d"  "字节数:%d"  "DM过滤掉的包数:%d"  "字节数:%d,n"
  2235.     ,StatisticInfo.p_dmRx,StatisticInfo.b_dmRx
  2236. ,StatisticInfo.p_dmFiltered,StatisticInfo.b_dmFiltered
  2237. ,StatisticInfo.p_dmTx,StatisticInfo.b_dmTx
  2238. );
  2239. fprintf(statFile,"内网:nt禁止IP的包数:%d"  "禁止ICMP分段的包数:%d"  "禁止ICMP类型的包数:%d"  "pong攻击包数:%d,n"  "smurf攻击的包数:%d"  "可疑offset的包数:%d"  "禁止tcp端口的包数:%d"  "禁止udp端口的包数:%dn禁止组播的包数:%d"  "禁止别的IP包数:%dn"
  2240. ,StatisticInfo.f_insideAcceptTable,StatisticInfo.f_insideIcmpFrag
  2241. ,StatisticInfo.f_insideIcmpType,StatisticInfo.f_insidePongDos
  2242. ,StatisticInfo.f_insideSmurfDos,StatisticInfo.f_insideSuspectOffset
  2243. ,StatisticInfo.f_insideTcpPort,StatisticInfo.f_insideUdpPort
  2244. ,StatisticInfo.f_insideMcast,StatisticInfo.f_insideOtherIp);
  2245.  fprintf(statFile,"外网:nt禁止IP的包数:%d"  "禁止ICMP分段的包数:%d"  "禁止ICMP类型的包数:%d"  "pong攻击包数:%dnsmurf攻击的包数:%d"  "可疑offset的包数:%d"  "禁止组播的包数:%dn" "禁止别的IP的包数:%dn"
  2246. ,StatisticInfo.f_outsideRejectTable,StatisticInfo.f_outsideIcmpFrag
  2247. ,StatisticInfo.f_outsideIcmpType,StatisticInfo.f_outsidePongDos
  2248. ,StatisticInfo.f_outsideSmurfDos,StatisticInfo.f_outsideSuspectOffset
  2249. ,StatisticInfo.f_outsideMcast,StatisticInfo.f_outsideOtherIp);
  2250. }
  2251. VOID GetStatisticsInfo(Statistics* StatisticInfo)
  2252. {
  2253. filter_command(DIOCGSTATS,(char*)StatisticInfo);
  2254. }
  2255. VOID mysearch()
  2256. {
  2257. /* ULONG group0,group1,group2,group3,group4,group5,group6,group7,group8,group9;
  2258. //没有则返回0
  2259. //主机树
  2260. group0 = treeLookup(active.addrTree, ntohl(inet_addr("192.168.130.205")), active.num_groups);
  2261. group1 = treeLookup(active.addrTree, ntohl(inet_addr("192.168.0.13")), active.num_groups);
  2262. group1 = treeLookup(active.addrTree, ntohl(inet_addr("192.168.0.14")), active.num_groups);
  2263. group2=treeLookup(active.addrTree, ntohl(inet_addr("192.168.3.11")), active.num_groups);//no
  2264. group2=treeLookup(active.addrTree, ntohl(inet_addr("192.168.11.11")), active.num_groups);//no
  2265. //允许树
  2266. group3 = treeLookup(active.acceptTree, ntohl(inet_addr("192.168.130.205")), active.num_groups);
  2267. group4 = treeLookup(active.acceptTree, ntohl(inet_addr("192.168.0.21")), active.num_groups);//no
  2268. group4 = treeLookup(active.acceptTree, ntohl(inet_addr("192.168.13.21")), active.num_groups);//no
  2269. //拒绝树
  2270. group5 = treeOutLookup(active.rejectTree, ntohl(inet_addr("192.168.130.205")), active.num_groups);
  2271. group6 = treeLookup(active.acceptTree, ntohl(inet_addr("192.168.13.21")), active.num_groups);//no
  2272. group7= treeLookup(active.In_FtpTree, ntohl(inet_addr("111.11.111.11")), active.num_groups);//no
  2273. group8 = treeLookup(active.In_HttpTree, ntohl(inet_addr("111.11.111.11")), active.num_groups);//no
  2274. group9 = treeLookup(active.In_SmtpTree, ntohl(inet_addr("111.11.111.11")), active.num_groups);//no
  2275. */
  2276. }