sppp.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Simplified Point-to-Point Protocol
  2.  * No negotiation, no address or ctl fields, 1-byte pids
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "iface.h"
  7. #include "ip.h"
  8. #include "slhc.h"
  9. #include "asy.h"
  10. #include "crc.h"
  11. #include "ahdlc.h"
  12. #include "sppp.h"
  13. #include "trace.h"
  14. static uint8 *putbyte(uint8 *cp,uint8 c);
  15. int
  16. sppp_init(ifp)
  17. struct iface *ifp;
  18. {
  19. char *ifn;
  20. ifp->ioctl = asy_ioctl;
  21. ifp->edv = slhc_init(16,16);
  22. ifp->rxproc = newproc(ifn = if_name(ifp," rx"),
  23. 512,sppp_rx,ifp->dev,ifp,NULL,0);
  24. free(ifn);
  25. return 0;
  26. }
  27. int
  28. sppp_free(ifp)
  29. struct iface *ifp;
  30. {
  31. free(ifp->edv);
  32. return 0;
  33. }
  34. /* Send an IP datagram using simplified PPP */
  35. int
  36. sppp_send(
  37. struct mbuf **bpp,
  38. struct iface *ifp,
  39. int32 gateway, /* Not used */
  40. uint8 tos /* Not used at this level */
  41. ){
  42. int type,protocol;
  43. struct slcompress *sp = ifp->edv;
  44. dump(ifp,IF_TRACE_OUT,*bpp);
  45. ifp->rawsndcnt++;
  46. ifp->lastsent = secclock();
  47. type = slhc_compress(sp,bpp,1);
  48. switch(type){
  49. default: /* "Can't happen" */
  50. case SL_TYPE_IP:
  51. protocol = PPP_IP_PROTOCOL;
  52. break;
  53. case SL_TYPE_COMPRESSED_TCP:
  54. protocol = PPP_COMPR_PROTOCOL;
  55. break;
  56. case SL_TYPE_UNCOMPRESSED_TCP:
  57. protocol = PPP_UNCOMP_PROTOCOL;
  58. break;
  59. }
  60. return sppp_output(ifp,protocol,bpp);
  61. }
  62. int
  63. sppp_output(
  64. struct iface *iface,
  65. int protocol,
  66. struct mbuf **bpp
  67. ){
  68. struct mbuf *obp;
  69. uint8 *cp;
  70. int c;
  71. uint16 fcs;
  72. fcs = FCS_START;
  73. obp = ambufw(6+2*len_p(*bpp)); /* Allocate worst-case */
  74. cp = obp->data;
  75. *cp++ = HDLC_FLAG;
  76. cp = putbyte(cp,(char)protocol);
  77. fcs = FCS(fcs,protocol);
  78. while((c = PULLCHAR(bpp)) != -1){
  79. fcs = FCS(fcs,c);
  80. cp = putbyte(cp,c);
  81. }
  82. free_p(bpp); /* Shouldn't be necessary */
  83. fcs ^= 0xffff;
  84. cp = putbyte(cp,fcs);
  85. cp = putbyte(cp,fcs >> 8);
  86. *cp++ = HDLC_FLAG;
  87. obp->cnt = cp - obp->data;
  88. return asy_send(iface->dev,&obp);
  89. }
  90. /* Add a byte to the PPP output stream, byte stuffing for transparency */
  91. static uint8 *
  92. putbyte(cp,c)
  93. uint8 *cp;
  94. uint8 c;
  95. {
  96. switch(c){
  97. case HDLC_FLAG:
  98. case HDLC_ESC_ASYNC:
  99. *cp++ = HDLC_ESC_ASYNC;
  100. *cp++ = c ^ HDLC_ESC_COMPL;
  101. break;
  102. default:
  103. *cp++ = c;
  104. }
  105. return cp;
  106. }
  107. /* Process simplified PPP line input */
  108. void
  109. sppp_rx(dev,p1,p2)
  110. int dev;
  111. void *p1;
  112. void *p2;
  113. {
  114. struct mbuf *bp;
  115. int c;
  116. struct ahdlc ahdlc;
  117. struct iface *ifp = (struct iface *)p1;
  118. struct slcompress *sp = ifp->edv;
  119. init_hdlc(&ahdlc,2048);
  120. for(;;){
  121. c = get_asy(dev);
  122. if((bp = ahdlcrx(&ahdlc,c)) == NULL)
  123. continue;
  124. c = PULLCHAR(&bp);
  125. switch(c){ /* Turn compressed IP/TCP back to normal */
  126. case PPP_COMPR_PROTOCOL:
  127. if(slhc_uncompress(sp,&bp) <= 0)
  128. c = -1; /* Failed; discard */
  129. else 
  130. c = PPP_IP_PROTOCOL;
  131. break;
  132. case PPP_UNCOMP_PROTOCOL:
  133. if(slhc_remember(sp,&bp) <= 0)
  134. c = -1; /* Failed; discard */
  135. else
  136. c = PPP_IP_PROTOCOL;
  137. break;
  138. }
  139. switch(c){
  140. case PPP_IP_PROTOCOL:
  141. net_route(ifp,&bp);
  142. break;
  143. case -1:
  144. break;
  145. default: /* Toss all unknown types */
  146. free_p(&bp);
  147. break;
  148. }
  149. }
  150. }