ipt_owner.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* Kernel module to match various things tied to sockets associated with
  2.    locally generated outgoing packets.
  3.    Copyright (C) 2000 Marc Boucher
  4.  */
  5. #include <linux/module.h>
  6. #include <linux/skbuff.h>
  7. #include <linux/file.h>
  8. #include <net/sock.h>
  9. #include <linux/netfilter_ipv4/ipt_owner.h>
  10. #include <linux/netfilter_ipv4/ip_tables.h>
  11. static int
  12. match_pid(const struct sk_buff *skb, pid_t pid)
  13. {
  14. struct task_struct *p;
  15. struct files_struct *files;
  16. int i;
  17. read_lock(&tasklist_lock);
  18. p = find_task_by_pid(pid);
  19. if (!p)
  20. goto out;
  21. task_lock(p);
  22. files = p->files;
  23. if(files) {
  24. read_lock(&files->file_lock);
  25. for (i=0; i < files->max_fds; i++) {
  26. if (fcheck_files(files, i) == skb->sk->socket->file) {
  27. read_unlock(&files->file_lock);
  28. task_unlock(p);
  29. read_unlock(&tasklist_lock);
  30. return 1;
  31. }
  32. }
  33. read_unlock(&files->file_lock);
  34. }
  35. task_unlock(p);
  36. out:
  37. read_unlock(&tasklist_lock);
  38. return 0;
  39. }
  40. static int
  41. match_sid(const struct sk_buff *skb, pid_t sid)
  42. {
  43. struct task_struct *p;
  44. struct file *file = skb->sk->socket->file;
  45. int i, found=0;
  46. read_lock(&tasklist_lock);
  47. for_each_task(p) {
  48. struct files_struct *files;
  49. if (p->session != sid)
  50. continue;
  51. task_lock(p);
  52. files = p->files;
  53. if (files) {
  54. read_lock(&files->file_lock);
  55. for (i=0; i < files->max_fds; i++) {
  56. if (fcheck_files(files, i) == file) {
  57. found = 1;
  58. break;
  59. }
  60. }
  61. read_unlock(&files->file_lock);
  62. }
  63. task_unlock(p);
  64. if(found)
  65. break;
  66. }
  67. read_unlock(&tasklist_lock);
  68. return found;
  69. }
  70. static int
  71. match(const struct sk_buff *skb,
  72.       const struct net_device *in,
  73.       const struct net_device *out,
  74.       const void *matchinfo,
  75.       int offset,
  76.       const void *hdr,
  77.       u_int16_t datalen,
  78.       int *hotdrop)
  79. {
  80. const struct ipt_owner_info *info = matchinfo;
  81. if (!skb->sk || !skb->sk->socket || !skb->sk->socket->file)
  82. return 0;
  83. if(info->match & IPT_OWNER_UID) {
  84. if((skb->sk->socket->file->f_uid != info->uid) ^
  85.     !!(info->invert & IPT_OWNER_UID))
  86. return 0;
  87. }
  88. if(info->match & IPT_OWNER_GID) {
  89. if((skb->sk->socket->file->f_gid != info->gid) ^
  90.     !!(info->invert & IPT_OWNER_GID))
  91. return 0;
  92. }
  93. if(info->match & IPT_OWNER_PID) {
  94. if (!match_pid(skb, info->pid) ^
  95.     !!(info->invert & IPT_OWNER_PID))
  96. return 0;
  97. }
  98. if(info->match & IPT_OWNER_SID) {
  99. if (!match_sid(skb, info->sid) ^
  100.     !!(info->invert & IPT_OWNER_SID))
  101. return 0;
  102. }
  103. return 1;
  104. }
  105. static int
  106. checkentry(const char *tablename,
  107.            const struct ipt_ip *ip,
  108.            void *matchinfo,
  109.            unsigned int matchsize,
  110.            unsigned int hook_mask)
  111. {
  112.         if (hook_mask
  113.             & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
  114.                 printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.n");
  115.                 return 0;
  116.         }
  117. if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
  118. return 0;
  119. return 1;
  120. }
  121. static struct ipt_match owner_match
  122. = { { NULL, NULL }, "owner", &match, &checkentry, NULL, THIS_MODULE };
  123. static int __init init(void)
  124. {
  125. return ipt_register_match(&owner_match);
  126. }
  127. static void __exit fini(void)
  128. {
  129. ipt_unregister_match(&owner_match);
  130. }
  131. module_init(init);
  132. module_exit(fini);
  133. MODULE_LICENSE("GPL");