/* NET/ROM header tracing routines
 * Copyright 1991 Phil Karn, KA9Q
 */
#include "global.h"
#ifdef NETROM
#include "mbuf.h"
#include "netrom.h"
#include "nr4.h"
#include "trace.h"
  
/* Display NET/ROM network and transport headers */
void
netrom_dump(fp,bpp,check)
FILE *fp;
struct mbuf **bpp;
int check;
{
    char src[AXALEN],dest[AXALEN];
    char tmp[AXBUF];
    char thdr[NR4MINHDR];
    register i;
  
    if(bpp == NULLBUFP || *bpp == NULLBUF)
        return;
    /* See if it is a routing broadcast */
    if(uchar(*(*bpp)->data) == NR3NODESIG) {
        (void)PULLCHAR(bpp);        /* Signature */
        pullup(bpp,tmp,ALEN);
        tmp[ALEN] = '\0';
        fprintf(fp,"NET/ROM Routing: %s\n",tmp);
        for(i = 0;i < NRDESTPERPACK;i++) {
            if (pullup(bpp,src,AXALEN) < AXALEN)
                break;
            fprintf(fp,"        %12s",pax25(tmp,src));
            pullup(bpp,tmp,ALEN);
            tmp[ALEN] = '\0';
            fprintf(fp,"%8s",tmp);
            pullup(bpp,src,AXALEN);
            fprintf(fp,"    %12s",pax25(tmp,src));
            tmp[0] = PULLCHAR(bpp);
            fprintf(fp,"    %3u\n",uchar(tmp[0]));
        }
        return;
    }
    /* See if it is a routing poll - WG7J */
    if(uchar(*(*bpp)->data) == NR3POLLSIG) {
        (void)PULLCHAR(bpp);        /* Signature */
        pullup(bpp,tmp,ALEN);
        tmp[ALEN] = '\0';
        fprintf(fp,"NET/ROM Poll: %s\n",tmp);
        return;
    }
    /* Decode network layer */
    pullup(bpp,src,AXALEN);
#ifdef MONITOR
    if (Trace_compact_header)
        fprintf(fp, "NET/ROM %s", pax25(tmp, src));
    else
#endif
        fprintf(fp,"NET/ROM: %s",pax25(tmp,src));
  
    pullup(bpp,dest,AXALEN);
    fprintf(fp,"->%s",pax25(tmp,dest));
  
    i = PULLCHAR(bpp);
#ifdef MONITOR
    if (!Trace_compact_header)
#endif
        fprintf(fp," ttl %d\n",i);
  
    /* Read first five bytes of "transport" header */
    pullup(bpp,thdr,NR4MINHDR);
    switch(thdr[4] & NR4OPCODE){
        case NR4OPPID:  /* network PID extension */
            if (thdr[0] == NRPROTO_IP && thdr[1] == NRPROTO_IP) {
#ifdef MONITOR
                if (Trace_compact_header)
                    fprintf(fp, " [IP]:\n");
#endif
                ip_dump(fp,bpp,check) ;
                return;
            }
            else
#ifdef MONITOR
                if (Trace_compact_header)
                    fprintf(fp, " [%x/%x]:\n",uchar(thdr[0]), uchar(thdr[1]));
                else
#endif
                    fprintf(fp,"         protocol family %x, proto %x",
                    uchar(thdr[0]), uchar(thdr[1])) ;
            break ;
        case NR4OPCONRQ:    /* Connect request */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " conn req %d/%d", uchar(thdr[0]), uchar(thdr[1]));
            else
#endif
                fprintf(fp,"         conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
            i = PULLCHAR(bpp);
#ifdef MONITOR
            if (!Trace_compact_header)
#endif
                fprintf(fp," wnd %d",i);
            pullup(bpp,src,AXALEN);
            fprintf(fp," %s",pax25(tmp,src));
            pullup(bpp,dest,AXALEN);
            fprintf(fp,"@%s",pax25(tmp,dest));
            break;
        case NR4OPCONAK:    /* Connect acknowledgement */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " conn ack %d/%d->%d/%d",
                uchar(thdr[0]), uchar(thdr[1]),
                uchar(thdr[2]), uchar(thdr[3]));
            else
#endif
                fprintf(fp,"         conn ack: ur ckt %d/%d my ckt %d/%d",
                uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
                uchar(thdr[3]));
            i = PULLCHAR(bpp);
#ifdef MONITOR
            if (!Trace_compact_header)
#endif
                fprintf(fp," wnd %d",i);
            break;
        case NR4OPDISRQ:    /* Disconnect request */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " disc %d/%d",uchar(thdr[0]), uchar(thdr[1]));
            else
#endif
                fprintf(fp,"         disc: ckt %d/%d",
                uchar(thdr[0]),uchar(thdr[1]));
            break;
        case NR4OPDISAK:    /* Disconnect acknowledgement */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " disc ack %d/%d", uchar(thdr[0]),uchar(thdr[1]));
            else
#endif
                fprintf(fp,"         disc ack: ckt %d/%d",
                uchar(thdr[0]),uchar(thdr[1]));
            break;
        case NR4OPINFO: /* Information (data) */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " %d/%d", uchar(thdr[0]),uchar(thdr[1]));
            else
            {
#endif
                fprintf(fp,"         info: ckt %d/%d",
                uchar(thdr[0]),uchar(thdr[1]));
                fprintf(fp," txseq %d rxseq %d",
                uchar(thdr[2]), uchar(thdr[3]));
#ifdef MONITOR
            }
#endif
            break;
        case NR4OPACK:  /* Information acknowledgement */
#ifdef MONITOR
            if (Trace_compact_header)
                fprintf(fp, " ack %d/%d",uchar(thdr[0]), uchar(thdr[1]));
            else
            {
#endif
                fprintf(fp,"         info ack: ckt %d/%d",
                uchar(thdr[0]),uchar(thdr[1]));
                fprintf(fp," txseq %d rxseq %d",
                uchar(thdr[2]), uchar(thdr[3]));
#ifdef MONITOR
            }
#endif
            break;
        default:
            fprintf(fp,"         unknown transport type %d",
            thdr[4] & 0x0f) ;
            break;
    }
    if(thdr[4] & NR4CHOKE)
        fprintf(fp," CHOKE");
    if(thdr[4] & NR4NAK)
        fprintf(fp," NAK");
    if(thdr[4] & NR4MORE)
        fprintf(fp," MORE");
    fprintf(fp,"\n");
}
  
#endif /* NETROM */
  
