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

Linux/Unix编程

开发平台:

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_comm(const struct sk_buff *skb, const char *comm)
  13. {
  14. struct task_struct *p;
  15. struct files_struct *files;
  16. int i;
  17. read_lock(&tasklist_lock);
  18. for_each_task(p) {
  19. if(strncmp(p->comm, comm, sizeof(p->comm)))
  20. continue;
  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. }
  37. read_unlock(&tasklist_lock);
  38. return 0;
  39. }
  40. static int
  41. match_pid(const struct sk_buff *skb, pid_t pid)
  42. {
  43. struct task_struct *p;
  44. struct files_struct *files;
  45. int i;
  46. read_lock(&tasklist_lock);
  47. p = find_task_by_pid(pid);
  48. if (!p)
  49. goto out;
  50. task_lock(p);
  51. files = p->files;
  52. if(files) {
  53. read_lock(&files->file_lock);
  54. for (i=0; i < files->max_fds; i++) {
  55. if (fcheck_files(files, i) == skb->sk->socket->file) {
  56. read_unlock(&files->file_lock);
  57. task_unlock(p);
  58. read_unlock(&tasklist_lock);
  59. return 1;
  60. }
  61. }
  62. read_unlock(&files->file_lock);
  63. }
  64. task_unlock(p);
  65. out:
  66. read_unlock(&tasklist_lock);
  67. return 0;
  68. }
  69. static int
  70. match_sid(const struct sk_buff *skb, pid_t sid)
  71. {
  72. struct task_struct *p;
  73. struct file *file = skb->sk->socket->file;
  74. int i, found=0;
  75. read_lock(&tasklist_lock);
  76. for_each_task(p) {
  77. struct files_struct *files;
  78. if (p->session != sid)
  79. continue;
  80. task_lock(p);
  81. files = p->files;
  82. if (files) {
  83. read_lock(&files->file_lock);
  84. for (i=0; i < files->max_fds; i++) {
  85. if (fcheck_files(files, i) == file) {
  86. found = 1;
  87. break;
  88. }
  89. }
  90. read_unlock(&files->file_lock);
  91. }
  92. task_unlock(p);
  93. if(found)
  94. break;
  95. }
  96. read_unlock(&tasklist_lock);
  97. return found;
  98. }
  99. static int
  100. match(const struct sk_buff *skb,
  101.       const struct net_device *in,
  102.       const struct net_device *out,
  103.       const void *matchinfo,
  104.       int offset,
  105.       const void *hdr,
  106.       u_int16_t datalen,
  107.       int *hotdrop)
  108. {
  109. const struct ipt_owner_info *info = matchinfo;
  110. if (!skb->sk || !skb->sk->socket || !skb->sk->socket->file)
  111. return 0;
  112. if(info->match & IPT_OWNER_UID) {
  113. if((skb->sk->socket->file->f_uid != info->uid) ^
  114.     !!(info->invert & IPT_OWNER_UID))
  115. return 0;
  116. }
  117. if(info->match & IPT_OWNER_GID) {
  118. if((skb->sk->socket->file->f_gid != info->gid) ^
  119.     !!(info->invert & IPT_OWNER_GID))
  120. return 0;
  121. }
  122. if(info->match & IPT_OWNER_PID) {
  123. if (!match_pid(skb, info->pid) ^
  124.     !!(info->invert & IPT_OWNER_PID))
  125. return 0;
  126. }
  127. if(info->match & IPT_OWNER_SID) {
  128. if (!match_sid(skb, info->sid) ^
  129.     !!(info->invert & IPT_OWNER_SID))
  130. return 0;
  131. }
  132. if(info->match & IPT_OWNER_COMM) {
  133. if (!match_comm(skb, info->comm) ^
  134.     !!(info->invert & IPT_OWNER_COMM))
  135. return 0;
  136. }
  137. return 1;
  138. }
  139. static int
  140. checkentry(const char *tablename,
  141.            const struct ipt_ip *ip,
  142.            void *matchinfo,
  143.            unsigned int matchsize,
  144.            unsigned int hook_mask)
  145. {
  146.         if (hook_mask
  147.             & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
  148.                 printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.n");
  149.                 return 0;
  150.         }
  151. if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
  152. return 0;
  153. return 1;
  154. }
  155. static struct ipt_match owner_match
  156. = { { NULL, NULL }, "owner", &match, &checkentry, NULL, THIS_MODULE };
  157. static int __init init(void)
  158. {
  159. return ipt_register_match(&owner_match);
  160. }
  161. static void __exit fini(void)
  162. {
  163. ipt_unregister_match(&owner_match);
  164. }
  165. module_init(init);
  166. module_exit(fini);
  167. MODULE_LICENSE("GPL");