ipt_unclean.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:14k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* Kernel module to match suspect packets. */
  2. #include <linux/module.h>
  3. #include <linux/skbuff.h>
  4. #include <linux/ip.h>
  5. #include <linux/udp.h>
  6. #include <linux/tcp.h>
  7. #include <linux/icmp.h>
  8. #include <net/checksum.h>
  9. #include <linux/netfilter_ipv4/ip_tables.h>
  10. #define limpk(format, args...)  
  11. do {  
  12. if (net_ratelimit())  
  13. printk("ipt_unclean: %s" format,  
  14.        embedded ? "(embedded packet) " : "" , ## args);  
  15. } while(0)
  16. enum icmp_error_status
  17. {
  18. ICMP_MAY_BE_ERROR,
  19. ICMP_IS_ERROR,
  20. ICMP_NOT_ERROR
  21. };
  22. struct icmp_info
  23. {
  24. size_t min_len, max_len;
  25. enum icmp_error_status err;
  26. u_int8_t min_code, max_code;
  27. };
  28. static int
  29. check_ip(struct iphdr *iph, size_t length, int embedded);
  30. /* ICMP-specific checks. */
  31. static int
  32. check_icmp(const struct icmphdr *icmph,
  33.    u_int16_t datalen,
  34.    unsigned int offset,
  35.    int more_frags,
  36.    int embedded)
  37. {
  38. static struct icmp_info info[]
  39. = { [ICMP_ECHOREPLY]
  40.     = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
  41.     [ICMP_DEST_UNREACH]
  42.     = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
  43.     [ICMP_SOURCE_QUENCH]
  44.     = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
  45.     [ICMP_REDIRECT]
  46.     = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
  47.     [ICMP_ECHO]
  48.     = { 8, 65536, ICMP_NOT_ERROR, 0, 0  },
  49.     /* Router advertisement. */
  50.     [9]
  51.     = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
  52.     /* Router solicitation. */
  53.     [10]
  54.     = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
  55.     [ICMP_TIME_EXCEEDED]
  56.     = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1  },
  57.     [ICMP_PARAMETERPROB]
  58.     = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
  59.     [ICMP_TIMESTAMP]
  60.     = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
  61.     [ICMP_TIMESTAMPREPLY]
  62.     = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
  63.     [ICMP_INFO_REQUEST]
  64.     = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
  65.     [ICMP_INFO_REPLY]
  66.     = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
  67.     [ICMP_ADDRESS]
  68.     = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
  69.     [ICMP_ADDRESSREPLY]
  70.     = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
  71. /* Can't do anything if it's a fragment. */
  72. if (offset)
  73. return 1;
  74. /* Must cover type and code. */
  75. if (datalen < 2) {
  76. limpk("ICMP len=%u too shortn", datalen);
  77. return 0;
  78. }
  79. /* If not embedded. */
  80. if (!embedded) {
  81. /* Bad checksum?  Don't print, just ignore. */
  82. if (!more_frags
  83.     && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
  84. return 0;
  85. /* CHECK: Truncated ICMP (even if first fragment). */
  86. if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
  87.     && info[icmph->type].min_len != 0
  88.     && datalen < info[icmph->type].min_len) {
  89. limpk("ICMP type %u len %u too shortn",
  90.       icmph->type, datalen);
  91. return 0;
  92. }
  93. /* CHECK: Check within known error ICMPs. */
  94. if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
  95.     && info[icmph->type].err == ICMP_IS_ERROR) {
  96. /* CHECK: Embedded packet must be at least
  97.    length of iph + 8 bytes. */
  98. struct iphdr *inner = (void *)icmph + 8;
  99. /* datalen > 8 since all ICMP_IS_ERROR types
  100.                            have min length > 8 */
  101. if (datalen - 8 < sizeof(struct iphdr)) {
  102. limpk("ICMP error internal way too shortn");
  103. return 0;
  104. }
  105. if (datalen - 8 < inner->ihl*4 + 8) {
  106. limpk("ICMP error internal too shortn");
  107. return 0;
  108. }
  109. if (!check_ip(inner, datalen - 8, 1))
  110. return 0;
  111. }
  112. } else {
  113. /* CHECK: Can't embed ICMP unless known non-error. */
  114. if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
  115.     || info[icmph->type].err != ICMP_NOT_ERROR) {
  116. limpk("ICMP type %u not embeddablen",
  117.       icmph->type);
  118. return 0;
  119. }
  120. }
  121. /* CHECK: Invalid ICMP codes. */
  122. if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
  123.     && (icmph->code < info[icmph->type].min_code
  124. || icmph->code > info[icmph->type].max_code)) {
  125. limpk("ICMP type=%u code=%un",
  126.       icmph->type, icmph->code);
  127. return 0;
  128. }
  129. /* CHECK: Above maximum length. */
  130. if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
  131.     && info[icmph->type].max_len != 0
  132.     && datalen > info[icmph->type].max_len) {
  133. limpk("ICMP type=%u too long: %u bytesn",
  134.       icmph->type, datalen);
  135. return 0;
  136. }
  137. switch (icmph->type) {
  138. case ICMP_PARAMETERPROB: {
  139. /* CHECK: Problem param must be within error packet's
  140.  * IP header. */
  141. struct iphdr *iph = (void *)icmph + 8;
  142. u_int32_t arg = ntohl(icmph->un.gateway);
  143. if (icmph->code == 0) {
  144. /* Code 0 means that upper 8 bits is pointer
  145.                            to problem. */
  146. if ((arg >> 24) >= iph->ihl*4) {
  147. limpk("ICMP PARAMETERPROB ptr = %un",
  148.       ntohl(icmph->un.gateway) >> 24);
  149. return 0;
  150. }
  151. arg &= 0x00FFFFFF;
  152. }
  153. /* CHECK: Rest must be zero. */
  154. if (arg) {
  155. limpk("ICMP PARAMETERPROB nonzero arg = %un",
  156.       arg);
  157. return 0;
  158. }
  159. break;
  160. }
  161. case ICMP_TIME_EXCEEDED:
  162. case ICMP_SOURCE_QUENCH:
  163. /* CHECK: Unused must be zero. */
  164. if (icmph->un.gateway != 0) {
  165. limpk("ICMP type=%u unused = %un",
  166.       icmph->type, ntohl(icmph->un.gateway));
  167. return 0;
  168. }
  169. break;
  170. }
  171. return 1;
  172. }
  173. /* UDP-specific checks. */
  174. static int
  175. check_udp(const struct iphdr *iph,
  176.   const struct udphdr *udph,
  177.   u_int16_t datalen,
  178.   unsigned int offset,
  179.   int more_frags,
  180.   int embedded)
  181. {
  182. /* Can't do anything if it's a fragment. */
  183. if (offset)
  184. return 1;
  185. /* CHECK: Must cover UDP header. */
  186. if (datalen < sizeof(struct udphdr)) {
  187. limpk("UDP len=%u too shortn", datalen);
  188. return 0;
  189. }
  190. /* Bad checksum?  Don't print, just say it's unclean. */
  191. /* FIXME: SRC ROUTE packets won't match checksum --RR */
  192. if (!more_frags && !embedded && udph->check
  193.     && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
  194.  csum_partial((char *)udph, datalen, 0)) != 0)
  195. return 0;
  196. /* CHECK: Destination port can't be zero. */
  197. if (!udph->dest) {
  198. limpk("UDP zero destination portn");
  199. return 0;
  200. }
  201. if (!more_frags) {
  202. if (!embedded) {
  203. /* CHECK: UDP length must match. */
  204. if (ntohs(udph->len) != datalen) {
  205. limpk("UDP len too short %u vs %un",
  206.       ntohs(udph->len), datalen);
  207. return 0;
  208. }
  209. } else {
  210. /* CHECK: UDP length be >= this truncated pkt. */
  211. if (ntohs(udph->len) < datalen) {
  212. limpk("UDP len too long %u vs %un",
  213.       ntohs(udph->len), datalen);
  214. return 0;
  215. }
  216. }
  217. } else {
  218. /* CHECK: UDP length must be > this frag's length. */
  219. if (ntohs(udph->len) <= datalen) {
  220. limpk("UDP fragment len too short %u vs %un",
  221.       ntohs(udph->len), datalen);
  222. return 0;
  223. }
  224. }
  225. return 1;
  226. }
  227. #define TH_FIN 0x01
  228. #define TH_SYN 0x02
  229. #define TH_RST 0x04
  230. #define TH_PUSH 0x08
  231. #define TH_ACK 0x10
  232. #define TH_URG 0x20
  233. #define TH_ECE 0x40
  234. #define TH_CWR 0x80
  235. /* TCP-specific checks. */
  236. static int
  237. check_tcp(const struct iphdr *iph,
  238.   const struct tcphdr *tcph,
  239.   u_int16_t datalen,
  240.   unsigned int offset,
  241.   int more_frags,
  242.   int embedded)
  243. {
  244. u_int8_t *opt = (u_int8_t *)tcph;
  245. u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
  246. u_int8_t tcpflags;
  247. int end_of_options = 0;
  248. size_t i;
  249. /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
  250. /* In fact, this is caught below (offset < 516). */
  251. /* Can't do anything if it's a fragment. */
  252. if (offset)
  253. return 1;
  254. /* CHECK: Smaller than minimal TCP hdr. */
  255. if (datalen < sizeof(struct tcphdr)) {
  256. if (!embedded) {
  257. limpk("Packet length %u < TCP header.n", datalen);
  258. return 0;
  259. }
  260. /* Must have ports available (datalen >= 8), from
  261.                    check_icmp which set embedded = 1 */
  262. /* CHECK: TCP ports inside ICMP error */
  263. if (!tcph->source || !tcph->dest) {
  264. limpk("Zero TCP ports %u/%u.n",
  265.       htons(tcph->source), htons(tcph->dest));
  266. return 0;
  267. }
  268. return 1;
  269. }
  270. /* CHECK: Smaller than actual TCP hdr. */
  271. if (datalen < tcph->doff * 4) {
  272. if (!embedded) {
  273. limpk("Packet length %u < actual TCP header.n",
  274.       datalen);
  275. return 0;
  276. } else
  277. return 1;
  278. }
  279. /* Bad checksum?  Don't print, just say it's unclean. */
  280. /* FIXME: SRC ROUTE packets won't match checksum --RR */
  281. if (!more_frags && !embedded
  282.     && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
  283.  csum_partial((char *)tcph, datalen, 0)) != 0)
  284. return 0;
  285. /* CHECK: TCP ports non-zero */
  286. if (!tcph->source || !tcph->dest) {
  287. limpk("Zero TCP ports %u/%u.n",
  288.       htons(tcph->source), htons(tcph->dest));
  289. return 0;
  290. }
  291. /* CHECK: TCP reserved bits zero. */
  292. if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
  293. limpk("TCP reserved bits not zeron");
  294. return 0;
  295. }
  296. /* CHECK: TCP flags. */
  297. tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
  298. if (tcpflags != TH_SYN
  299.     && tcpflags != (TH_SYN|TH_ACK)
  300. && tcpflags != TH_RST
  301.     && tcpflags != (TH_RST|TH_ACK)
  302.     && tcpflags != (TH_RST|TH_ACK|TH_PUSH)
  303.     && tcpflags != (TH_FIN|TH_ACK)
  304.     && tcpflags != TH_ACK
  305.     && tcpflags != (TH_ACK|TH_PUSH)
  306.     && tcpflags != (TH_ACK|TH_URG)
  307.     && tcpflags != (TH_ACK|TH_URG|TH_PUSH)
  308.     && tcpflags != (TH_FIN|TH_ACK|TH_PUSH)
  309.     && tcpflags != (TH_FIN|TH_ACK|TH_URG)
  310.     && tcpflags != (TH_FIN|TH_ACK|TH_URG|TH_PUSH)) {
  311. limpk("TCP flags bad: %un", tcpflags);
  312. return 0;
  313. }
  314. for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
  315. switch (opt[i]) {
  316. case 0:
  317. end_of_options = 1;
  318. i++;
  319. break;
  320. case 1:
  321. i++;
  322. break;
  323. default:
  324. /* CHECK: options after EOO. */
  325. if (end_of_options) {
  326. limpk("TCP option %u after endn",
  327.       opt[i]);
  328. return 0;
  329. }
  330. /* CHECK: options at tail. */
  331. else if (i+1 >= tcph->doff * 4) {
  332. limpk("TCP option %u at tailn",
  333.       opt[i]);
  334. return 0;
  335. }
  336. /* CHECK: zero-length options. */
  337. else if (opt[i+1] == 0) {
  338. limpk("TCP option %u 0 lenn",
  339.       opt[i]);
  340. return 0;
  341. }
  342. /* CHECK: oversize options. */
  343. else if (&opt[i] + opt[i+1] > endhdr) {
  344. limpk("TCP option %u at %Zu too longn",
  345.       (unsigned int) opt[i], i);
  346. return 0;
  347. }
  348. /* Move to next option */
  349. i += opt[i+1];
  350. }
  351. }
  352. return 1;
  353. }
  354. /* Returns 1 if ok */
  355. /* Standard IP checks. */
  356. static int
  357. check_ip(struct iphdr *iph, size_t length, int embedded)
  358. {
  359. u_int8_t *opt = (u_int8_t *)iph;
  360. u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
  361. int end_of_options = 0;
  362. void *protoh;
  363. size_t datalen;
  364. unsigned int i;
  365. unsigned int offset;
  366. /* Should only happen for local outgoing raw-socket packets. */
  367. /* CHECK: length >= ip header. */
  368. if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
  369. limpk("Packet length %Zu < IP header.n", length);
  370. return 0;
  371. }
  372. offset = ntohs(iph->frag_off) & IP_OFFSET;
  373. protoh = (void *)iph + iph->ihl * 4;
  374. datalen = length - iph->ihl * 4;
  375. /* CHECK: Embedded fragment. */
  376. if (embedded && offset) {
  377. limpk("Embedded fragment.n");
  378. return 0;
  379. }
  380. for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
  381. switch (opt[i]) {
  382. case 0:
  383. end_of_options = 1;
  384. i++;
  385. break;
  386. case 1:
  387. i++;
  388. break;
  389. default:
  390. /* CHECK: options after EOO. */
  391. if (end_of_options) {
  392. limpk("IP option %u after endn",
  393.       opt[i]);
  394. return 0;
  395. }
  396. /* CHECK: options at tail. */
  397. else if (i+1 >= iph->ihl * 4) {
  398. limpk("IP option %u at tailn",
  399.       opt[i]);
  400. return 0;
  401. }
  402. /* CHECK: zero-length or one-length options. */
  403. else if (opt[i+1] < 2) {
  404. limpk("IP option %u %u lenn",
  405.       opt[i], opt[i+1]);
  406. return 0;
  407. }
  408. /* CHECK: oversize options. */
  409. else if (&opt[i] + opt[i+1] > endhdr) {
  410. limpk("IP option %u at %u too longn",
  411.       opt[i], i);
  412. return 0;
  413. }
  414. /* Move to next option */
  415. i += opt[i+1];
  416. }
  417. }
  418. /* Fragment checks. */
  419. /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
  420. if ((ntohs(iph->frag_off) & IP_MF)
  421.     && (ntohs(iph->tot_len) % 8) != 0) {
  422. limpk("Truncated fragment %u long.n", ntohs(iph->tot_len));
  423. return 0;
  424. }
  425. /* CHECK: Oversize fragment a-la Ping of Death. */
  426. if (offset * 8 + datalen > 65535) {
  427. limpk("Oversize fragment to %u.n", offset * 8);
  428. return 0;
  429. }
  430. /* CHECK: DF set and offset or MF set. */
  431. if ((ntohs(iph->frag_off) & IP_DF)
  432.     && (offset || (ntohs(iph->frag_off) & IP_MF))) {
  433. limpk("DF set and offset=%u, MF=%u.n",
  434.       offset, ntohs(iph->frag_off) & IP_MF);
  435. return 0;
  436. }
  437. /* CHECK: Zero-sized fragments. */
  438. if ((offset || (ntohs(iph->frag_off) & IP_MF))
  439.     && datalen == 0) {
  440. limpk("Zero size fragment offset=%un", offset);
  441. return 0;
  442. }
  443. /* Note: we can have even middle fragments smaller than this:
  444.    consider a large packet passing through a 600MTU then
  445.    576MTU link: this gives a fragment of 24 data bytes.  But
  446.    everyone packs fragments largest first, hence a fragment
  447.    can't START before 576 - MAX_IP_HEADER_LEN. */
  448. /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
  449.    down to 128 (576 taken from RFC 791: All hosts must be
  450.    prepared to accept datagrams of up to 576 octets).  Use 128
  451.    here. */
  452. #define MIN_LIKELY_MTU 128
  453. /* CHECK: Min size of first frag = 128. */
  454. if ((ntohs(iph->frag_off) & IP_MF)
  455.     && offset == 0
  456.     && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
  457. limpk("First fragment size %u < %un", ntohs(iph->tot_len),
  458.       MIN_LIKELY_MTU);
  459. return 0;
  460. }
  461. /* CHECK: Min offset of frag = 128 - IP hdr len. */
  462. if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
  463. limpk("Fragment starts at %u < %un", offset * 8,
  464.       MIN_LIKELY_MTU - iph->ihl * 4);
  465. return 0;
  466. }
  467. /* CHECK: Protocol specification non-zero. */
  468. if (iph->protocol == 0) {
  469. limpk("Zero protocoln");
  470. return 0;
  471. }
  472. /* Per-protocol checks. */
  473. switch (iph->protocol) {
  474. case IPPROTO_ICMP:
  475. return check_icmp(protoh, datalen, offset,
  476.   (ntohs(iph->frag_off) & IP_MF),
  477.   embedded);
  478. case IPPROTO_UDP:
  479. return check_udp(iph, protoh, datalen, offset,
  480.  (ntohs(iph->frag_off) & IP_MF),
  481.  embedded);
  482. case IPPROTO_TCP:
  483. return check_tcp(iph, protoh, datalen, offset,
  484.  (ntohs(iph->frag_off) & IP_MF),
  485.  embedded);
  486. default:
  487. /* Ignorance is bliss. */
  488. return 1;
  489. }
  490. }
  491. static int
  492. match(const struct sk_buff *skb,
  493.       const struct net_device *in,
  494.       const struct net_device *out,
  495.       const void *matchinfo,
  496.       int offset,
  497.       const void *hdr,
  498.       u_int16_t datalen,
  499.       int *hotdrop)
  500. {
  501. return !check_ip(skb->nh.iph, skb->len, 0);
  502. }
  503. /* Called when user tries to insert an entry of this type. */
  504. static int
  505. checkentry(const char *tablename,
  506.    const struct ipt_ip *ip,
  507.    void *matchinfo,
  508.    unsigned int matchsize,
  509.    unsigned int hook_mask)
  510. {
  511. if (matchsize != IPT_ALIGN(0))
  512. return 0;
  513. return 1;
  514. }
  515. static struct ipt_match unclean_match
  516. = { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
  517. static int __init init(void)
  518. {
  519. return ipt_register_match(&unclean_match);
  520. }
  521. static void __exit fini(void)
  522. {
  523. ipt_unregister_match(&unclean_match);
  524. }
  525. module_init(init);
  526. module_exit(fini);
  527. MODULE_LICENSE("GPL");