home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / AX25.C < prev    next >
C/C++ Source or Header  |  1992-04-11  |  12KB  |  443 lines

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