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

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Low level AX.25 code:
  2.  *  incoming frame processing (including digipeating)
  3.  *  IP encapsulation
  4.  *  digipeater routing
  5.  *
  6.  * Copyright 1991 Phil Karn, KA9Q
  7.  */
  8. #include <stdio.h>
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "iface.h"
  12. #include "arp.h"
  13. #include "slip.h"
  14. #include "ax25.h"
  15. #include "lapb.h"
  16. #include "netrom.h"
  17. #include "ip.h"
  18. #include "devparam.h"
  19. #include <ctype.h>
  20. /* List of AX.25 multicast addresses in network format (shifted ascii).
  21.  * Only the first entry is used for transmission, but an incoming
  22.  * packet with any one of these destination addresses is recognized
  23.  * as a multicast.
  24.  */
  25. uint8 Ax25multi[][AXALEN] = {
  26. 'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* QST */
  27. 'M'<<1, 'A'<<1, 'I'<<1, 'L'<<1, ' '<<1, ' '<<1, '0'<<1, /* MAIL */
  28. 'N'<<1, 'O'<<1, 'D'<<1, 'E'<<1, 'S'<<1, ' '<<1, '0'<<1, /* NODES */
  29. 'I'<<1, 'D'<<1, ' '<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* ID */
  30. 'O'<<1, 'P'<<1, 'E'<<1, 'N'<<1, ' '<<1, ' '<<1, '0'<<1, /* OPEN */
  31. 'C'<<1, 'Q'<<1, ' '<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* CQ */
  32. 'B'<<1, 'E'<<1, 'A'<<1, 'C'<<1, 'O'<<1, 'N'<<1, '0'<<1, /* BEACON */
  33. 'R'<<1, 'M'<<1, 'N'<<1, 'C'<<1, ' '<<1, ' '<<1, '0'<<1, /* RMNC */
  34. 'A'<<1, 'L'<<1, 'L'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1, /* ALL */
  35. '',
  36. };
  37. uint8 Mycall[AXALEN];
  38. struct ax_route *Ax_routes; /* Routing table header */
  39. int Digipeat = 1; /* Controls digipeating */
  40. int
  41. axi_send(
  42. struct mbuf **bpp,
  43. struct iface *iface,
  44. int32 gateway,
  45. uint8 tos
  46. ){
  47. return axui_send(bpp,iface,gateway,tos);
  48. }
  49. /* Send IP datagrams across an AX.25 link */
  50. int
  51. axui_send(
  52. struct mbuf **bpp,
  53. struct iface *iface,
  54. int32 gateway,
  55. uint8 tos
  56. ){
  57. struct mbuf *tbp;
  58. uint8 *hw_addr;
  59. struct ax25_cb *axp;
  60. if((hw_addr = res_arp(iface,ARP_AX25,gateway,bpp)) == NULL)
  61. return 0; /* Wait for address resolution */
  62. /* UI frames are used for any one of the following three conditions:
  63.  * 1. The "low delay" bit is set in the type-of-service field.
  64.  * 2. The "reliability" TOS bit is NOT set and the interface is in
  65.  *    datagram mode.
  66.  * 3. The destination is the broadcast address (this is helpful
  67.  *    when broadcasting on an interface that's in connected mode).
  68.  */
  69. if((tos & IP_COS) == DELAY
  70.  || ((tos & IP_COS) != RELIABILITY && (iface->send == axui_send))
  71.  || addreq(hw_addr,Ax25multi[0])){
  72. /* Use UI frame */
  73. return (*iface->output)(iface,hw_addr,iface->hwaddr,PID_IP,bpp);
  74. }
  75. /* Reliability is needed; use I-frames in AX.25 connection */
  76. if((axp = find_ax25(hw_addr)) == NULL){
  77. /* Open a new connection */
  78. axp = open_ax25(iface,iface->hwaddr,hw_addr,
  79.  AX_ACTIVE,Axwindow,s_arcall,s_atcall,s_ascall,-1);
  80. if(axp == NULL){
  81. free_p(bpp);
  82. return -1;
  83. }
  84. }
  85. if(axp->state == LAPB_DISCONNECTED){
  86. est_link(axp);
  87. lapbstate(axp,LAPB_SETUP);
  88. }
  89. /* Insert the PID */
  90. pushdown(bpp,NULL,1);
  91. (*bpp)->data[0] = PID_IP;
  92. if((tbp = segmenter(bpp,axp->paclen)) == NULL){
  93. free_p(bpp);
  94. return -1;
  95. }
  96. return send_ax25(axp,&tbp,-1);
  97. }
  98. /* Add header and send connectionless (UI) AX.25 packet.
  99.  * Note that the calling order here must match enet_output
  100.  * since ARP also uses it.
  101.  */
  102. int
  103. ax_output(
  104. struct iface *iface, /* Interface to use; overrides routing table */
  105. uint8 *dest, /* Destination AX.25 address (7 bytes, shifted) */
  106. uint8 *source, /* Source AX.25 address (7 bytes, shifted) */
  107. uint16 pid, /* Protocol ID */
  108. struct mbuf **bpp /* Data field (follows PID) */
  109. ){
  110. /* Prepend pid to data */
  111. pushdown(bpp,NULL,1);
  112. (*bpp)->data[0] = (uint8)pid;
  113. return axsend(iface,dest,source,LAPB_COMMAND,UI,bpp);
  114. }
  115. /* Common subroutine for sendframe() and ax_output() */
  116. int
  117. axsend(
  118. struct iface *iface, /* Interface to use; overrides routing table */
  119. uint8 *dest, /* Destination AX.25 address (7 bytes, shifted) */
  120. uint8 *source, /* Source AX.25 address (7 bytes, shifted) */
  121. int cmdrsp, /* Command/response indication */
  122. int ctl, /* Control field */
  123. struct mbuf **bpp /* Data field (includes PID) */
  124. ){
  125. struct ax25 addr;
  126. struct ax_route *axr;
  127. uint8 *idest;
  128. int rval;
  129. /* If the source addr is unspecified, use the interface address */
  130. if(source[0] == '')
  131. source = iface->hwaddr;
  132. /* If there's a digipeater route, get it */
  133. axr = ax_lookup(dest);
  134. memcpy(addr.dest,dest,AXALEN);
  135. memcpy(addr.source,source,AXALEN);
  136. addr.cmdrsp = cmdrsp;
  137. if(axr != NULL){
  138. memcpy(addr.digis,axr->digis,axr->ndigis*AXALEN);
  139. addr.ndigis = axr->ndigis;
  140. idest = addr.digis[0];
  141. } else {
  142. addr.ndigis = 0;
  143. idest = dest;
  144. }
  145. addr.nextdigi = 0;
  146. /* Allocate mbuf for control field, and fill in */
  147. pushdown(bpp,NULL,1);
  148. (*bpp)->data[0] = ctl;
  149. htonax25(&addr,bpp);
  150. /* This shouldn't be necessary because redirection has already been
  151.  * done at the IP router layer, but just to be safe...
  152.  */
  153. if(iface->forw != NULL){
  154. logsrc(iface->forw,iface->forw->hwaddr);
  155. logdest(iface->forw,idest);
  156. rval = (*iface->forw->raw)(iface->forw,bpp);
  157. } else {
  158. logsrc(iface,iface->hwaddr);
  159. logdest(iface,idest);
  160. rval = (*iface->raw)(iface,bpp);
  161. }
  162. return rval;
  163. }
  164. /* Process incoming AX.25 packets.
  165.  * After optional tracing, the address field is examined. If it is
  166.  * directed to us as a digipeater, repeat it.  If it is addressed to
  167.  * us or to QST-0, kick it upstairs depending on the protocol ID.
  168.  */
  169. void
  170. ax_recv(
  171. struct iface *iface,
  172. struct mbuf **bpp
  173. ){
  174. uint8 control;
  175. struct ax25 hdr;
  176. struct ax25_cb *axp;
  177. struct ax_route *axr;
  178. uint8 (*mpp)[AXALEN];
  179. int mcast;
  180. uint8 *isrc,*idest; /* "immediate" source and destination */
  181. /* Pull header off packet and convert to host structure */
  182. if(ntohax25(&hdr,bpp) < 0){
  183. /* Something wrong with the header */
  184. free_p(bpp);
  185. return;
  186. }
  187. /* If there were digis in this packet and at least one has
  188.  * been passed, then the last passed digi is the immediate source.
  189.  * Otherwise it is the original source.
  190.  */
  191. if(hdr.ndigis != 0 && hdr.nextdigi != 0)
  192. isrc = hdr.digis[hdr.nextdigi-1];
  193. else
  194. isrc = hdr.source;
  195. /* If there are digis in this packet and not all have been passed,
  196.  * then the immediate destination is the next digi. Otherwise it
  197.  * is the final destination.
  198.  */
  199. if(hdr.ndigis != 0 && hdr.nextdigi != hdr.ndigis)
  200. idest = hdr.digis[hdr.nextdigi];
  201. else
  202. idest = hdr.dest;
  203. /* Don't log our own packets if we overhear them, as they're
  204.  * already logged by axsend() and by the digipeater code.
  205.  */
  206. if(!addreq(isrc,iface->hwaddr)){
  207. logsrc(iface,isrc);
  208. logdest(iface,idest);
  209. }
  210. /* Examine immediate destination for a multicast address */
  211. mcast = 0;
  212. for(mpp = Ax25multi;(*mpp)[0] != '';mpp++){
  213. if(addreq(idest,*mpp)){
  214. mcast = 1;
  215. break;
  216. }
  217. }
  218. if(!mcast && !addreq(idest,iface->hwaddr)){
  219. /* Not a broadcast, and not addressed to us. Inhibit
  220.  * transmitter to avoid colliding with addressed station's
  221.  * response, and discard packet.
  222.  */
  223. if(iface->ioctl != NULL)
  224. (*iface->ioctl)(iface,PARAM_MUTE,1,-1);
  225. free_p(bpp);
  226. return;
  227. }
  228. if(!mcast && iface->ioctl != NULL){
  229. /* Packet was sent to us; abort transmit inhibit */
  230. (*iface->ioctl)(iface,PARAM_MUTE,1,0);
  231. }
  232. /* At this point, packet is either addressed to us, or is
  233.  * a multicast.
  234.  */
  235. if(hdr.nextdigi < hdr.ndigis){
  236. /* Packet requests digipeating. See if we can repeat it. */
  237. if(Digipeat && !mcast){
  238. /* Yes, kick it back out. htonax25 will set the
  239.  * repeated bit.
  240.  */
  241. hdr.nextdigi++;
  242. htonax25(&hdr,bpp);
  243. if(iface->forw != NULL){
  244. logsrc(iface->forw,iface->forw->hwaddr);
  245. logdest(iface->forw,hdr.digis[hdr.nextdigi]);
  246. (*iface->forw->raw)(iface->forw,bpp);
  247. } else {
  248. logsrc(iface,iface->hwaddr);
  249. logdest(iface,hdr.digis[hdr.nextdigi]);
  250. (*iface->raw)(iface,bpp);
  251. }
  252. }
  253. free_p(bpp); /* Dispose if not forwarded */
  254. return;
  255. }
  256. /* If we reach this point, then the packet has passed all digis,
  257.  * and is either addressed to us or is a multicast.
  258.  */
  259. if(*bpp == NULL)
  260. return; /* Nothing left */
  261. /* If there's no locally-set entry in the routing table and
  262.  * this packet has digipeaters, create or update it. Leave
  263.  * local routes alone.
  264.  */
  265. if(((axr = ax_lookup(hdr.source)) == NULL || axr->type == AX_AUTO)
  266.  && hdr.ndigis > 0){
  267. uint8 digis[MAXDIGIS][AXALEN];
  268. int i,j;
  269. /* Construct reverse digipeater path */
  270. for(i=hdr.ndigis-1,j=0;i >= 0;i--,j++){
  271. memcpy(digis[j],hdr.digis[i],AXALEN);
  272. digis[j][ALEN] &= ~(E|REPEATED);
  273. }
  274. ax_add(hdr.source,AX_AUTO,digis,hdr.ndigis);
  275. }
  276. /* Sneak a peek at the control field. This kludge is necessary because
  277.  * AX.25 lacks a proper protocol ID field between the address and LAPB
  278.  * sublayers; a control value of UI indicates that LAPB is to be
  279.  * bypassed.
  280.  */
  281. control = *(*bpp)->data & ~PF;
  282. if(control == UI){
  283. int pid;
  284. struct axlink *ipp;
  285. (void) PULLCHAR(bpp);
  286. if((pid = PULLCHAR(bpp)) == -1)
  287. return; /* No PID */
  288. /* Find network level protocol and hand it off */
  289. for(ipp = Axlink;ipp->funct != NULL;ipp++){
  290. if(ipp->pid == pid)
  291. break;
  292. }
  293. if(ipp->funct != NULL)
  294. (*ipp->funct)(iface,NULL,hdr.source,hdr.dest,bpp,mcast);
  295. else
  296. free_p(bpp);
  297. return;
  298. }
  299. /* Everything from here down is connected-mode LAPB, so ignore
  300.  * multicasts
  301.  */
  302. if(mcast){
  303. free_p(bpp);
  304. return;
  305. }
  306. /* Find the source address in hash table */
  307. if((axp = find_ax25(hdr.source)) == NULL){
  308. /* Create a new ax25 entry for this guy,
  309.  * insert into hash table keyed on his address,
  310.  * and initialize table entries
  311.  */
  312. if((axp = cr_ax25(hdr.source)) == NULL){
  313. free_p(bpp);
  314. return;
  315. }
  316. /* Swap source and destination */
  317. memcpy(axp->remote,hdr.source,AXALEN);
  318. memcpy(axp->local,hdr.dest,AXALEN);
  319. axp->iface = iface;
  320. }
  321. if(hdr.cmdrsp == LAPB_UNKNOWN)
  322. axp->proto = V1; /* Old protocol in use */
  323. lapb_input(axp,hdr.cmdrsp,bpp);
  324. }
  325. /* Find a route for an AX.25 address */
  326. struct ax_route *
  327. ax_lookup(
  328. uint8 *target
  329. ){
  330. register struct ax_route *axr;
  331. struct ax_route *axlast = NULL;
  332. for(axr = Ax_routes; axr != NULL; axlast=axr,axr = axr->next){
  333. if(addreq(axr->target,target)){
  334. if(axr != Ax_routes){
  335. /* Move entry to top of list to speed
  336.  * future searches
  337.  */
  338. axlast->next = axr->next;
  339. axr->next = Ax_routes;
  340. Ax_routes = axr;
  341. }
  342. return axr;
  343. }
  344. }
  345. return axr;
  346. }
  347. /* Add an entry to the AX.25 routing table */
  348. struct ax_route *
  349. ax_add(
  350. uint8 *target,
  351. int type,
  352. uint8 digis[][AXALEN],
  353. int ndigis
  354. ){
  355. register struct ax_route *axr;
  356. if(ndigis < 0 || ndigis > MAXDIGIS)
  357. return NULL;
  358. if((axr = ax_lookup(target)) == NULL){
  359. axr = (struct ax_route *)callocw(1,sizeof(struct ax_route));
  360. axr->next = Ax_routes;
  361. Ax_routes = axr;
  362. memcpy(axr->target,target,AXALEN);
  363. axr->ndigis = ndigis;
  364. }
  365. axr->type = type;
  366. if(axr->ndigis != ndigis)
  367. axr->ndigis = ndigis;
  368. memcpy(axr->digis,digis[0],ndigis*AXALEN);
  369. return axr;
  370. }
  371. int
  372. ax_drop(
  373. uint8 *target
  374. ){
  375. register struct ax_route *axr;
  376. struct ax_route *axlast = NULL;
  377. for(axr = Ax_routes;axr != NULL;axlast=axr,axr=axr->next)
  378. if(memcmp(axr->target,target,AXALEN) == 0)
  379. break;
  380. if(axr == NULL)
  381. return -1; /* Not in table! */
  382. if(axlast != NULL)
  383. axlast->next = axr->next;
  384. else
  385. Ax_routes = axr->next;
  386. free(axr);
  387. return 0;
  388. }