免费注册 查看新帖 |

Chinaunix

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

Linux内核网络问题,各位大牛一定要进来看一下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-05-31 09:11 |只看该作者 |倒序浏览
Linux内核版本2.6.18


socket函数的系统调用函数如下:
我在其中对发送的数据和接收的数据试图进行输出操作,如带有注释的两行代码所示。结果是,可以输出发送数据,但是无法输出接收的数据(是直接没有输出任何的数据,不是输出乱码)。
  1. asmlinkage long sys_socketcall(int call, unsigned long __user *args)
  2. {
  3.          unsigned long a[6];
  4.          unsigned long a0, a1;
  5.          int err;

  6.          if (call < 1 || call > SYS_RECVMSG)
  7.                  return -EINVAL;

  8.          /* copy_from_user should be SMP safe. */
  9.          if (copy_from_user(a, args, nargs[call]))
  10.                  return -EFAULT;

  11.          err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
  12.          if (err)
  13.                  return err;

  14.          a0 = a[0];
  15.          a1 = a[1];

  16.          switch (call) {
  17.          case SYS_SOCKET:
  18.                  err = sys_socket(a0, a1, a[2]);
  19.                  break;
  20.          case SYS_BIND:
  21.                  err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
  22.                  break;
  23.          case SYS_CONNECT:
  24.                  err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
  25.                  break;
  26.          case SYS_LISTEN:
  27.                  err = sys_listen(a0, a1);
  28.                  break;
  29.          case SYS_ACCEPT:
  30.                  err =
  31.                      sys_accept(a0, (struct sockaddr __user *)a1,
  32.                                 (int __user *)a[2]);
  33.                  break;
  34.          case SYS_GETSOCKNAME:
  35.                  err =
  36.                      sys_getsockname(a0, (struct sockaddr __user *)a1,
  37.                                      (int __user *)a[2]);
  38.                  break;
  39.          case SYS_GETPEERNAME:
  40.                  err =
  41.                      sys_getpeername(a0, (struct sockaddr __user *)a1,
  42.                                      (int __user *)a[2]);
  43.                  break;
  44.          case SYS_SOCKETPAIR:
  45.                  err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
  46.                  break;
  47.          case SYS_SEND:
  48.                  err = sys_send(a0, (void __user *)a1, a[2], a[3]);
  49.                  break;
  50.          case SYS_SENDTO:
  51.                  printk("sendto a1=%s\n",(char *)a1);//a1是指向要发送的用户数据的指针,可以打印
  52.                  err = sys_sendto(a0, (void __user *)a1, a[2], a[3],
  53.                                   (struct sockaddr __user *)a[4], a[5]);
  54.                  break;
  55.          case SYS_RECV:
  56.                  err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
  57.                  break;
  58.          case SYS_RECVFROM:
  59.                  printk("recvfrom a1=%s\n",(char *)a1);//a1是指向要接收的用户数据的指针,不能打印???
  60.                  err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  61.                                     (struct sockaddr __user *)a[4],
  62.                                     (int __user *)a[5]);
  63.                  break;


复制代码
从sys_sendto和sys_recvfrom的参数a1,我们知道,
a1 是一个指针,当发送时,指向要发送的数据,当接收时,指向要接收的数据

各位大牛,给点看法,思路。在此先谢过了!

论坛徽章:
0
2 [报告]
发表于 2011-05-31 10:27 |只看该作者
你这种写法是错误的,因为a1的值可能是无效的,或指向的内存是无效的。

其次recvfrom指向的空间内容是随机的,即使打印出来也没有什么意义
你应该放在recvfrom后面来打印

论坛徽章:
0
3 [报告]
发表于 2011-05-31 11:02 |只看该作者
回复 2# qtdszws


    多谢大侠指点,真是醍醐灌顶啊。
   我仍有一个疑问,就是,在sys_recvfrom()接收到数据之后,系统是不是直接退出内核态,进入用户态了?那如果想在数据传到应用程序之前,对接收到的数据进行处理(比如解密),应该在哪下手呢?
   望大侠赐教!

论坛徽章:
0
4 [报告]
发表于 2011-05-31 12:24 |只看该作者
看看ipsec
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP