home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / AXHEARD.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  7KB  |  288 lines

  1. /* AX25 link callsign monitoring. Also contains beginnings of
  2.  * an automatic link quality monitoring scheme (incomplete)
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <ctype.h>
  7. #include "global.h"
  8. #ifdef AX25
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "ax25.h"
  12. #include "ip.h"
  13. #include "timer.h"
  14.   
  15. #define iscallsign(c) ((isupper(c)) || (isdigit(c)) || (c ==' '))
  16. int axheard_filter_flag = AXHEARD_PASS;
  17.   
  18. static struct lq *al_create __ARGS((struct iface *ifp,char *addr));
  19. static struct ld *ad_lookup __ARGS((struct iface *ifp,char *addr,int sort));
  20. static struct ld *ad_create __ARGS((struct iface *ifp,char *addr));
  21. struct lq *Lq;
  22. struct ld *Ld;
  23.   
  24. #ifdef  notdef
  25. /* Send link quality reports to interface */
  26. void
  27. genrpt(ifp)
  28. struct iface *ifp;
  29. {
  30.     struct mbuf *bp;
  31.     register char *cp;
  32.     int i;
  33.     struct lq *lp;
  34.     int maxentries,nentries;
  35.   
  36.     maxentries = (Paclen - LQHDR) / LQENTRY;
  37.     if((bp = alloc_mbuf(Paclen)) == NULLBUF)
  38.         return;
  39.     cp = bp->data;
  40.     nentries = 0;
  41.   
  42.     /* Build and emit header */
  43.     cp = putlqhdr(cp,LINKVERS,Ip_addr);
  44.   
  45.     /* First entry is for ourselves. Since we're examining the Axsent
  46.      * variable before we've sent this frame, add one to it so it'll
  47.      * match the receiver's count after he gets this frame.
  48.      */
  49.     cp = putlqentry(cp,ifp->hwaddr,Axsent+1);
  50.     nentries++;
  51.   
  52.     /* Now add entries from table */
  53.     for(lp = lq;lp != NULLLQ;lp = lp->next){
  54.         cp = putlqentry(cp,&lp->addr,lp->currxcnt);
  55.         if(++nentries >= MAXENTRIES){
  56.             /* Flush */
  57.             bp->cnt = nentries*LQENTRY + LQHDR;
  58.             ax_output(ifp,Ax25multi[0],ifp->hwaddr,PID_LQ,bp);
  59.             if((bp = alloc_mbuf(Paclen)) == NULLBUF)
  60.                 return;
  61.             cp = bp->data;
  62.         }
  63.     }
  64.     if(nentries > 0){
  65.         bp->cnt = nentries*LQENTRY + LQHDR;
  66.         ax_output(ifp,Ax25multi[0],ifp->hwaddr,LQPID,bp);
  67.     } else {
  68.         free_p(bp);
  69.     }
  70. }
  71.   
  72. /* Pull the header off a link quality packet */
  73. void
  74. getlqhdr(hp,bpp)
  75. struct lqhdr *hp;
  76. struct mbuf **bpp;
  77. {
  78.     hp->version = pull16(bpp);
  79.     hp->ip_addr = pull32(bpp);
  80. }
  81.   
  82. /* Put a header on a link quality packet.
  83.  * Return pointer to buffer immediately following header
  84.  */
  85. char *
  86. putlqhdr(cp,version,ip_addr)
  87. register char *cp;
  88. int16 version;
  89. int32 ip_addr;
  90. {
  91.     cp = put16(cp,version);
  92.     return put32(cp,ip_addr);
  93. }
  94.   
  95. /* Pull an entry off a link quality packet */
  96. void
  97. getlqentry(ep,bpp)
  98. struct lqentry *ep;
  99. struct mbuf **bpp;
  100. {
  101.     pullup(bpp,ep->addr,AXALEN);
  102.     ep->count = pull32(bpp);
  103. }
  104.   
  105. /* Put an entry on a link quality packet
  106.  * Return pointer to buffer immediately following header
  107.  */
  108. char *
  109. putlqentry(cp,addr,count)
  110. char *cp;
  111. char *addr;
  112. int32 count;
  113. {
  114.     memcpy(cp,addr,AXALEN);
  115.     cp += AXALEN;
  116.     return put32(cp,count);
  117. }
  118. #endif
  119.   
  120. /* Log the source address of an incoming packet */
  121. void
  122. logsrc(ifp,addr)
  123. struct iface *ifp;
  124. char *addr;
  125. {
  126.     register struct lq *lp;
  127.   
  128.     if(axheard_filter_flag & AXHEARD_NOSRC || !(ifp->flags & LOG_AXHEARD))
  129.         return;
  130.     {
  131.         register unsigned char c;
  132.         register int i = 0;
  133.         while(i < AXALEN-1){
  134.             c = *(addr+i);
  135.             c >>= 1;
  136.             if(!iscallsign(c))
  137.                 return;
  138.             i++;
  139.         }
  140.     }
  141.   
  142.     if((lp = al_lookup(ifp,addr,1)) == NULLLQ)
  143.         if((lp = al_create(ifp,addr)) == NULLLQ)
  144.             return;
  145.     lp->currxcnt++;
  146.     lp->time = secclock();
  147. }
  148. /* Log the destination address of an incoming packet */
  149. void
  150. logdest(ifp,addr)
  151. struct iface *ifp;
  152. char *addr;
  153. {
  154.     register struct ld *lp;
  155.   
  156.     if(axheard_filter_flag & AXHEARD_NODST || !(ifp->flags & LOG_AXHEARD))
  157.         return;
  158.     {
  159.         register unsigned char c;
  160.         register int i = 0;
  161.         while(i < AXALEN-1){
  162.             c = *(addr+i);
  163.             c >>= 1;
  164.             if(!iscallsign(c))
  165.                 return;
  166.             i++;
  167.         }
  168.     }
  169.   
  170.     if((lp = ad_lookup(ifp,addr,1)) == NULLLD)
  171.         if((lp = ad_create(ifp,addr)) == NULLLD)
  172.             return;
  173.     lp->currxcnt++;
  174.     lp->time = secclock();
  175. }
  176. /* Look up an entry in the source data base */
  177. struct lq *
  178. al_lookup(ifp,addr,sort)
  179. struct iface *ifp;
  180. char *addr;
  181. int sort;
  182. {
  183.     register struct lq *lp;
  184.     struct lq *lplast = NULLLQ;
  185.   
  186.     for(lp = Lq;lp != NULLLQ;lplast = lp,lp = lp->next){
  187.         if((lp->iface == ifp) && addreq(lp->addr,addr)){
  188.             if(sort && lplast != NULLLQ){
  189.                 /* Move entry to top of list */
  190.                 lplast->next = lp->next;
  191.                 lp->next = Lq;
  192.                 Lq = lp;
  193.             }
  194.             return lp;
  195.         }
  196.     }
  197.     return NULLLQ;
  198. }
  199.   
  200. extern int Maxax25heard;
  201.   
  202. /* Create a new entry in the source database */
  203. /* If there are too many entries, override the oldest one - WG7J */
  204. static struct lq *
  205. al_create(ifp,addr)
  206. struct iface *ifp;
  207. char *addr;
  208. {
  209.     static int numdb;
  210.     register struct lq *lp;
  211.     struct lq *lplast = NULLLQ;
  212.   
  213.     if(Maxax25heard && numdb == Maxax25heard) {
  214.         /* find and use last one in list */
  215.         for(lp = Lq;lp->next != NULLLQ;lplast = lp,lp = lp->next);
  216.         /* delete entry from end */
  217.         if(lplast)
  218.             lplast->next = NULLLQ;
  219.         else    /* Only one entry, and maxax25heard = 1 ! */
  220.             Lq = NULLLQ;
  221.         lp->currxcnt = 0;
  222.     } else {    /* create a new entry */
  223.         numdb++;
  224.         lp = (struct lq *)callocw(1,sizeof(struct lq));
  225.     }
  226.     memcpy(lp->addr,addr,AXALEN);
  227.     lp->iface = ifp;
  228.     lp->next = Lq;
  229.     Lq = lp;
  230.   
  231.     return lp;
  232. }
  233.   
  234. /* Look up an entry in the destination database */
  235. static struct ld *
  236. ad_lookup(ifp,addr,sort)
  237. struct iface *ifp;
  238. char *addr;
  239. int sort;
  240. {
  241.     register struct ld *lp;
  242.     struct ld *lplast = NULLLD;
  243.   
  244.     for(lp = Ld;lp != NULLLD;lplast = lp,lp = lp->next){
  245.         if((lp->iface == ifp) && addreq(lp->addr,addr)){
  246.             if(sort && lplast != NULLLD){
  247.                 /* Move entry to top of list */
  248.                 lplast->next = lp->next;
  249.                 lp->next = Ld;
  250.                 Ld = lp;
  251.             }
  252.             return lp;
  253.         }
  254.     }
  255.     return NULLLD;
  256. }
  257. /* Create a new entry in the destination database */
  258. static struct ld *
  259. ad_create(ifp,addr)
  260. struct iface *ifp;
  261. char *addr;
  262. {
  263.     static int numdb;
  264.     register struct ld *lp;
  265.     struct ld *lplast = NULLLD;
  266.   
  267.     if(Maxax25heard && numdb == Maxax25heard) { /* find and use last one in list */
  268.         for(lp = Ld;lp->next != NULLLD;lplast = lp,lp = lp->next);
  269.         /* delete entry from end */
  270.         if(lplast)
  271.             lplast->next = NULLLD;
  272.         else
  273.             Ld = NULLLD;
  274.         lp->currxcnt = 0;
  275.     } else {    /* create a new entry */
  276.         numdb++;
  277.         lp = (struct ld *)callocw(1,sizeof(struct ld));
  278.     }
  279.     memcpy(lp->addr,addr,AXALEN);
  280.     lp->iface = ifp;
  281.     lp->next = Ld;
  282.     Ld = lp;
  283.   
  284.     return lp;
  285. }
  286. #endif /* AX25 */
  287.   
  288.