Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1879145
  • 博文数量: 376
  • 博客积分: 2147
  • 博客等级: 大尉
  • 技术积分: 3642
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-06 10:47
文章分类

全部博文(376)

文章存档

2019年(3)

2017年(28)

2016年(15)

2015年(17)

2014年(182)

2013年(16)

2012年(115)

我的朋友

分类: 嵌入式

2014-01-13 12:33:23

Hi again,

Jan Du Caju wrote:
> >  Ing. CIP Alejandro Celi Mariategui wrote:
> >
> >  (Sorry, but my english is very bad)
> >  Hi,
> >  I compile with p-o-m the server kernel with IPLIMIT Patch by Gerd
> >  Knorr
> >  [1]
> >  It work fine, i can limit ex: max 10 TCP connections on the server,
> >  but i want to limit the UDP connections to 10 (max).
> >  How I can do it?

>    This week I made a updlimit patch (shameless copy of iplimit ;-)
>    I will post it this afternoon/evening when I have more time (and
>    a cross post to the netfilter-devel list. Maybe they like it)

In attachment you will find:
udplimit.patch
udplimit.patch.config.in
udplimit.patch.configure.help
udplimit.patch.help
udplimit.patch.makefile

put those under /base/ directory

in the directory you run: ./runme base
(don't forget to select udplimit ;-)

recompile your kernel (with Connections/UDP limit match support
CONFIG_IP_NF_MATCH_UDPLIMIT ;-)

Place the other file attachment (libipt_udplimit.c) in the directory
/extensions/

in this directory you will also find the file Makefile where you add
udplimit just after iplimit

recompile iptables

Hope this helps (it works for me :-)

Greetz,
Jan.
--------------------------------------------- KULeuvenNet -----

  1. diff -urN -x *~ -x [Cc]onfig.* -x Makefile
  2. vanilla-2.4.21-pre4/net/ipv4/netfilter/ipt_udplimit.c
  3. linux-2.4.21-pre4/net/ipv4/netfilter/ipt_udplimit.c
  4. --- vanilla-2.4.21-pre4/net/ipv4/netfilter/ipt_udplimit.c       Fri Feb 21
  5. 17:20:55 2003
  6. +++ linux-2.4.21-pre4/net/ipv4/netfilter/ipt_udplimit.c Fri Feb 21 17:17:38 2003
  7. @@ -0,0 +1,215 @@
  8. +/*
  9. + * netfilter module to limit the number of parallel udp
  10. + * connections per IP address.
  11. + * Jan Du Caju
  12. + *
  13. + * based on ...
  14. + * iplimit (in fact a shameless copy ;-)
  15. + *   (c) 2000 Gerd Knorr
  16. + *   Nov 2002: Martin Bene :
  17. + *             only ignore TIME_WAIT or gone connections
  18. + *
  19. + *
  20. + * Kernel module to match connection tracking information.
  21. + * GPL (C) 1999  Rusty Russell (rusty@xxxxxxxxxxxxxxx).
  22. + */
  23. +#include
  24. +#include
  25. +#include
  26. +#include
  27. +#include
  28. +#include
  29. +#include
  30. +
  31. +#define DEBUG 0
  32. +
  33. +MODULE_LICENSE("GPL");
  34. +
  35. +/* we'll save the tuples of all connections we care about */
  36. +struct ipt_iplimit_conn
  37. +{
  38. +        struct list_head list;
  39. +       struct ip_conntrack_tuple tuple;
  40. +};
  41. +
  42. +struct ipt_iplimit_data {
  43. +       spinlock_t lock;
  44. +       struct list_head iphash[256];
  45. +};
  46. +
  47. +static int ipt_iphash(u_int32_t addr)
  48. +{
  49. +       int hash;
  50. +
  51. +       hash  =  addr        & 0xff;
  52. +       hash ^= (addr >>  8) & 0xff;
  53. +       hash ^= (addr >> 16) & 0xff;
  54. +       hash ^= (addr >> 24) & 0xff;
  55. +       return hash;
  56. +}
  57. +
  58. +static int count_them(struct ipt_iplimit_data *data,
  59. +                     u_int32_t addr, u_int32_t mask,
  60. +                     struct ip_conntrack *ct)
  61. +{
  62. +       int addit = 1, matches = 0;
  63. +       struct ip_conntrack_tuple tuple;
  64. +       struct ip_conntrack_tuple_hash *found;
  65. +       struct ipt_iplimit_conn *conn;
  66. +       struct list_head *hash,*lh;
  67. +
  68. +       spin_lock(&data->lock);
  69. +       tuple = ct->tuplehash[0].tuple;
  70. +       hash = &data->iphash[ipt_iphash(addr & mask)];
  71. +
  72. +       /* check the saved connections */
  73. +       for (lh = hash->next; lh != hash; lh = lh->next) {
  74. +               conn = list_entry(lh,struct ipt_iplimit_conn,list);
  75. +               found = ip_conntrack_find_get(&conn->tuple,ct);
  76. +               if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
  77. +                   found != NULL) {
  78. +                       addit = 0;
  79. +               }
  80. +#if DEBUG
  81. +               printk("ipt_udplimit [%d]: src=%u.%u.%u.%u:%d
  82. dst=%u.%u.%u.%u:%d\n",
  83. +                      ipt_iphash(addr & mask),
  84. +                      NIPQUAD(conn->tuple.src.ip),
  85. ntohs(conn->tuple.src.u.udp.port),
  86. +                      NIPQUAD(conn->tuple.dst.ip),
  87. ntohs(conn->tuple.dst.u.udp.port));
  88. +#endif
  89. +               if (NULL == found) {
  90. +                       /* this one is gone */
  91. +                       lh = lh->prev;
  92. +                       list_del(lh->next);
  93. +                       kfree(conn);
  94. +                       continue;
  95. +               }
  96. +               if ((addr & mask) == (conn->tuple.src.ip & mask)) {
  97. +                       /* same source IP address -> be counted! */
  98. +                       matches++;
  99. +               }
  100. +               nf_conntrack_put(&found->ctrack->infos[0]);
  101. +       }
  102. +       if (addit) {
  103. +               /* save the new connection in our list */
  104. +#if DEBUG
  105. +               printk("ipt_udplimit [%d]: src=%u.%u.%u.%u:%d
  106. dst=%u.%u.%u.%u:%d new\n",
  107. +                      ipt_iphash(addr & mask),
  108. +                      NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
  109. +                      NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
  110. +#endif
  111. +               conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
  112. +               if (NULL == conn)
  113. +                       return -1;
  114. +               memset(conn,0,sizeof(*conn));
  115. +               INIT_LIST_HEAD(&conn->list);
  116. +               conn->tuple = tuple;
  117. +               list_add(&conn->list,hash);
  118. +               matches++;
  119. +       }
  120. +       spin_unlock(&data->lock);
  121. +       return matches;
  122. +}
  123. +
  124. +static int
  125. +match(const struct sk_buff *skb,
  126. +      const struct net_device *in,
  127. +      const struct net_device *out,
  128. +      const void *matchinfo,
  129. +      int offset,
  130. +      const void *hdr,
  131. +      u_int16_t datalen,
  132. +      int *hotdrop)
  133. +{
  134. +       const struct ipt_iplimit_info *info = matchinfo;
  135. +       int connections, match;
  136. +       struct ip_conntrack *ct;
  137. +       enum ip_conntrack_info ctinfo;
  138. +
  139. +       ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
  140. +       if (NULL == ct) {
  141. +               printk("ipt_udplimit: Oops: invalid ct state ?\n");
  142. +               *hotdrop = 1;
  143. +               return 0;
  144. +       }
  145. +       connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
  146. +       if (-1 == connections) {
  147. +               printk("ipt_udplimit: Hmm, kmalloc failed :-(\n");
  148. +               *hotdrop = 1; /* let's free some memory :-) */
  149. +               return 0;
  150. +       }
  151. +        match = (info->inverse) ? (connections <= info->limit) : (connections
  152. > info->limit);
  153. +#if DEBUG
  154. +       printk("ipt_udplimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
  155. +              "connections=%d limit=%d match=%s\n",
  156. +              NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
  157. +              connections, info->limit, match ? "yes" : "no");
  158. +#endif
  159. +
  160. +       return match;
  161. +}
  162. +
  163. +static int check(const char *tablename,
  164. +                const struct ipt_ip *ip,
  165. +                void *matchinfo,
  166. +                unsigned int matchsize,
  167. +                unsigned int hook_mask)
  168. +{
  169. +       struct ipt_iplimit_info *info = matchinfo;
  170. +       int i;
  171. +
  172. +       /* verify size */
  173. +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_iplimit_info)))
  174. +               return 0;
  175. +
  176. +       /* refuse anything but udp */
  177. +       if (ip->proto != IPPROTO_UDP)
  178. +               return 0;
  179. +
  180. +       /* init private data */
  181. +       info->data = kmalloc(sizeof(struct ipt_iplimit_data),GFP_KERNEL);
  182. +       spin_lock_init(&(info->data->lock));
  183. +       for (i = 0; i < 256; i++)
  184. +               INIT_LIST_HEAD(&(info->data->iphash));
  185. +      
  186. +       return 1;
  187. +}
  188. +
  189. +static void destroy(void *matchinfo, unsigned int matchinfosize)
  190. +{
  191. +       struct ipt_iplimit_info *info = matchinfo;
  192. +       struct ipt_iplimit_conn *conn;
  193. +       struct list_head *hash;
  194. +       int i;
  195. +
  196. +       /* cleanup */
  197. +       for (i = 0; i < 256; i++) {
  198. +               hash = &(info->data->iphash);
  199. +               while (hash != hash->next) {
  200. +                       conn = list_entry(hash->next,struct
  201. ipt_iplimit_conn,list);
  202. +                       list_del(hash->next);
  203. +                       kfree(conn);
  204. +               }
  205. +       }
  206. +       kfree(info->data);
  207. +}
  208. +
  209. +static struct ipt_match udplimit_match
  210. += { { NULL, NULL }, "udplimit", &match, &check, &destroy, THIS_MODULE };
  211. +
  212. +static int __init init(void)
  213. +{
  214. +       /* NULL if ip_conntrack not a module */
  215. +       if (ip_conntrack_module)
  216. +               __MOD_INC_USE_COUNT(ip_conntrack_module);
  217. +       return ipt_register_match(&udplimit_match);
  218. +}
  219. +
  220. +static void __exit fini(void)
  221. +{
  222. +       ipt_unregister_match(&udplimit_match);
  223. +       if (ip_conntrack_module)
  224. +               __MOD_DEC_USE_COUNT(ip_conntrack_module);
  225. +}
  226. +
  227. +module_init(init);
  228. +module_exit(fini);

  229.     dep_tristate '  Connection state match support' CONFIG_IP_NF_MATCH_STATE
  230. $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
  231.     dep_tristate '  Connections/UDP limit match support'
  232. CONFIG_IP_NF_MATCH_UDPLIMIT $CONFIG_IP_NF_IPTABLES

  233. obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
  234. obj-$(CONFIG_IP_NF_MATCH_UDPLIMIT) += ipt_udplimit.o

  235. Author: Gerd Knorr
  236.         Jan Du Caju (I just made a shameless copy
  237.         of iplimit of Gerd Knorr ;-)
  238. Status: ItWorksForMe[tm]

  239. This adds CONFIG_IP_NF_MATCH_UDPLIMIT match allows you to restrict the
  240. number of parallel UDP connections to a server per client IP address
  241. (or address block).

  242. Examples:

  243. # allow 5 udp connections per client host
  244. iptables -p udp -m udplimit --udplimit-above 5 -j REJECT

  245. # you can also match the other way around:
  246. iptables -p udp -m udplimit ! --udplimit-above 5 -j ACCEPT

  247. # limit the nr of parallel http requests to 16 per class C sized
  248. # network (24 bit netmask)
  249. iptables -p udp --dport 161 -m udplimit --udplimit-above 16             \
  250.         --iplimit-mask 24 -j REJECT

  251. CONFIG_IP_NF_MATCH_STATE
  252. Connections/UDP limit match support
  253. CONFIG_IP_NF_MATCH_UDPLIMIT
  254.   This match allows you to restrict the number of parallel UDP
  255.   connections to a server per client IP address (or address block).

  256.   If you want to compile it as a module, say M here and read
  257.   Documentation/modules.txt.  If unsure, say `N'.

  258. /* Shared library add-on to iptables to add state tracking support. */
  259. #include
  260. #include
  261. #include
  262. #include
  263. #include
  264. #include
  265. #include
  266. #include
  267. #include

  268. /* Function which prints out usage message. */
  269. static void
  270. help(void)
  271. {
  272.         printf(
  273. "udplimit v%s options:\n"
  274. "[!] --udplimit-above n         match if the number of existing udp connections
  275. is (not) above n\n"
  276. " --udplimit-mask n             group hosts using mask\n"
  277. "\n", IPTABLES_VERSION);
  278. }

  279. static struct option opts[] = {
  280.         { "udplimit-above", 1, 0, '1' },
  281.         { "udplimit-mask",  1, 0, '2' },
  282.         {0}
  283. };

  284. /* Initialize the match. */
  285. static void
  286. init(struct ipt_entry_match *m, unsigned int *nfcache)
  287. {
  288.         /* Can't cache this */
  289.         *nfcache |= NFC_UNKNOWN;
  290. }

  291. /* Function which parses command options; returns true if it
  292.    ate an option */
  293. static int
  294. parse(int c, char **argv, int invert, unsigned int *flags,
  295.       const struct ipt_entry *entry,
  296.       unsigned int *nfcache,
  297.       struct ipt_entry_match **match)
  298. {
  299.         struct ipt_iplimit_info *info = (struct
  300. ipt_iplimit_info*)(*match)->data;

  301.         if (0 == (*flags & 2)) {
  302.                 /* set default mask unless we've already seen a mask option */
  303.                 info->mask = htonl(0xFFFFFFFF);
  304.         }

  305.         switch (c) {
  306.         case '1':
  307.                 check_inverse(optarg, &invert, &optind, 0);
  308.                 info->limit = atoi(argv[optind-1]);
  309.                 info->inverse = invert;
  310.                 *flags |= 1;
  311.                 break;

  312.         case '2':
  313.                 info->mask = htonl(0xFFFFFFFF << (32 - atoi(argv[optind-1])));
  314.                 *flags |= 2;
  315.                 break;

  316.         default:
  317.                 return 0;
  318.         }

  319.         return 1;
  320. }

  321. /* Final check */
  322. static void final_check(unsigned int flags)
  323. {
  324.         if (!flags & 1)
  325.                 exit_error(PARAMETER_PROBLEM, "You must specify
  326. `--udplimit-above'");
  327. }

  328. static int
  329. count_bits(u_int32_t mask)
  330. {
  331.         int i, bits;

  332.         for (bits = 0, i = 31; i >= 0; i--) {
  333.                 if (mask & htonl((u_int32_t)1 << i)) {
  334.                         bits++;
  335.                         continue;
  336.                 }
  337.                 break;
  338.         }
  339.         return bits;
  340. }

  341. /* Prints out the matchinfo. */
  342. static void
  343. print(const struct ipt_ip *ip,
  344.       const struct ipt_entry_match *match,
  345.       int numeric)
  346. {
  347.         struct ipt_iplimit_info *info = (struct ipt_iplimit_info*)match->data;

  348.         printf("#conn/%d %s %d ", count_bits(info->mask),
  349.                info->inverse ? "<" : ">", info->limit);
  350. }

  351. /* Saves the matchinfo in parsable form to stdout. */
  352. static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
  353. {
  354.         struct ipt_iplimit_info *info = (struct ipt_iplimit_info*)match->data;

  355.         printf("%s--udplimit-above %d ",info->inverse ? "! " : "",info->limit);
  356.         printf("--udplimit-mask %d ",count_bits(info->mask));
  357. }

  358. static struct iptables_match udplimit = {
  359.         name:           "udplimit",
  360.         version:        IPTABLES_VERSION,
  361.         size:           IPT_ALIGN(sizeof(struct ipt_iplimit_info)),
  362.         userspacesize:  offsetof(struct ipt_iplimit_info,data),
  363.         help:           help,
  364.         init:           init,
  365.         parse:          parse,
  366.         final_check:    final_check,
  367.         print:          print,
  368.         save:           save,
  369.         extra_opts:     opts
  370. };

  371. void _init(void)
  372. {
  373.         register_match(&udplimit);
  374. }
阅读(3934) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~