Linux内核网络问题,各位大牛一定要进来看一下

发布于 2022-10-15 05:39:19 字数 6876 浏览 14 评论 0

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 是一个指针,当发送时,指向要发送的数据,当接收时,指向要接收的数据

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

高冷爸爸 2022-10-22 05:39:19

你这种写法是错误的,因为a1的值可能是无效的,或指向的内存是无效的。

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

嗫嚅 2022-10-22 05:39:19

回复 2# qtdszws

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

怪我闹别瞎闹 2022-10-22 05:39:19

看看ipsec

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文