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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* net/atm/pvc.c - ATM PVC sockets */
  2. /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  3. #include <linux/config.h>
  4. #include <linux/net.h> /* struct socket, struct net_proto,
  5.    struct proto_ops */
  6. #include <linux/atm.h> /* ATM stuff */
  7. #include <linux/atmdev.h> /* ATM devices */
  8. #include <linux/atmclip.h> /* Classical IP over ATM */
  9. #include <linux/errno.h> /* error codes */
  10. #include <linux/kernel.h> /* printk */
  11. #include <linux/init.h>
  12. #include <linux/skbuff.h>
  13. #include <linux/bitops.h>
  14. #include <net/sock.h> /* for sock_no_* */
  15. #ifdef CONFIG_ATM_CLIP
  16. #include <net/atmclip.h>
  17. #endif
  18. #include "resources.h" /* devs and vccs */
  19. #include "common.h" /* common for PVCs and SVCs */
  20. #ifndef NULL
  21. #define NULL 0
  22. #endif
  23. static int pvc_shutdown(struct socket *sock,int how)
  24. {
  25. return 0;
  26. }
  27. static int pvc_bind(struct socket *sock,struct sockaddr *sockaddr,
  28.     int sockaddr_len)
  29. {
  30. struct sockaddr_atmpvc *addr;
  31. struct atm_vcc *vcc;
  32. if (sockaddr_len != sizeof(struct sockaddr_atmpvc)) return -EINVAL;
  33. addr = (struct sockaddr_atmpvc *) sockaddr;
  34. if (addr->sap_family != AF_ATMPVC) return -EAFNOSUPPORT;
  35. vcc = ATM_SD(sock);
  36. if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
  37. if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
  38. if (vcc->vpi != ATM_VPI_UNSPEC) addr->sap_addr.vpi = vcc->vpi;
  39. if (vcc->vci != ATM_VCI_UNSPEC) addr->sap_addr.vci = vcc->vci;
  40. }
  41. return atm_connect(sock,addr->sap_addr.itf,addr->sap_addr.vpi,
  42.     addr->sap_addr.vci);
  43. }
  44. static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
  45.     int sockaddr_len,int flags)
  46. {
  47. return pvc_bind(sock,sockaddr,sockaddr_len);
  48. }
  49. static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
  50.     int *sockaddr_len,int peer)
  51. {
  52. struct sockaddr_atmpvc *addr;
  53. struct atm_vcc *vcc = ATM_SD(sock);
  54. if (!vcc->dev || !test_bit(ATM_VF_ADDR,&vcc->flags)) return -ENOTCONN;
  55.         *sockaddr_len = sizeof(struct sockaddr_atmpvc);
  56. addr = (struct sockaddr_atmpvc *) sockaddr;
  57. addr->sap_family = AF_ATMPVC;
  58. addr->sap_addr.itf = vcc->dev->number;
  59. addr->sap_addr.vpi = vcc->vpi;
  60. addr->sap_addr.vci = vcc->vci;
  61. return 0;
  62. }
  63. static struct proto_ops SOCKOPS_WRAPPED(pvc_proto_ops) = {
  64. family: PF_ATMPVC,
  65. release: atm_release,
  66. bind: pvc_bind,
  67. connect: pvc_connect,
  68. socketpair: sock_no_socketpair,
  69. accept: sock_no_accept,
  70. getname: pvc_getname,
  71. poll: atm_poll,
  72. ioctl: atm_ioctl,
  73. listen: sock_no_listen,
  74. shutdown: pvc_shutdown,
  75. setsockopt: atm_setsockopt,
  76. getsockopt: atm_getsockopt,
  77. sendmsg: atm_sendmsg,
  78. recvmsg: atm_recvmsg,
  79. mmap: sock_no_mmap,
  80. sendpage: sock_no_sendpage,
  81. };
  82. #include <linux/smp_lock.h>
  83. SOCKOPS_WRAP(pvc_proto, PF_ATMPVC);
  84. static int pvc_create(struct socket *sock,int protocol)
  85. {
  86. sock->ops = &pvc_proto_ops;
  87. return atm_create(sock,protocol,PF_ATMPVC);
  88. }
  89. static struct net_proto_family pvc_family_ops = {
  90. PF_ATMPVC,
  91. pvc_create,
  92. 0, /* no authentication */
  93. 0, /* no encryption */
  94. 0 /* no encrypt_net */
  95. };
  96. /*
  97.  * Initialize the ATM PVC protocol family
  98.  */
  99. static int __init atmpvc_init(void)
  100. {
  101. int error;
  102. error = sock_register(&pvc_family_ops);
  103. if (error < 0) {
  104. printk(KERN_ERR "ATMPVC: can't register (%d)",error);
  105. return error;
  106. }
  107. #ifdef CONFIG_ATM_CLIP
  108. atm_clip_init();
  109. #endif
  110. #ifdef CONFIG_PROC_FS
  111. error = atm_proc_init();
  112. if (error) printk("atm_proc_init fails with %dn",error);
  113. #endif
  114. return 0;
  115. }
  116. module_init(atmpvc_init);