#include <u.h>
#include <libc.h>
#include <ip.h>
#include "dat.h"
#include "protos.h"

typedef struct Hdr      Hdr;
struct Hdr
{
       uchar   flags;
       uchar   ln[4];  /* optional, present if L flag set*/
};

enum
{
       FLHDR=  1,      /* sizeof(flags) */
       LNHDR=  4,      /* sizeof(ln) */
};

enum
{
       FlagL = 1<<7,
       FlagM = 1<<6,
       FlagS = 1<<5,
       Version = (1<<2)|(1<<1)|(1<<0),
};

static Mux p_mux[] =
{
       { "dump", 0, },
       { 0 }
};

static char*
flags(int f)
{
       static char fl[20];
       char *p;

       p = fl;
       if(f & FlagS)
               *p++ = 'S';
       if(f & FlagM)
               *p++ = 'M';
       if(f & FlagL)
               *p++ = 'L';
       *p = 0;
       return fl;
}

static int
p_seprint(Msg *m)
{
       Hdr *h;

       if(m->pe - m->ps < FLHDR)
               return -1;

       h = (Hdr*)m->ps;
       m->ps += FLHDR;

       if (h->flags & FlagL) {
               if(m->pe - m->ps < LNHDR)
                       return -1;
               else
                       m->ps += LNHDR;
       }

       /* next protocol  depending on type*/
       demux(p_mux, 0, 0, m, &dump);

       m->p = seprint(m->p, m->e, "ver=%1d", h->flags & Version);
       m->p = seprint(m->p, m->e, " fl=%s", flags(h->flags));

       if (h->flags & FlagL)
               m->p = seprint(m->p, m->e, " totallen=%1d", NetL(h->ln));

       /* these are not in the header, just print them for our convenience */
       m->p = seprint(m->p, m->e, " dataln=%1zd", m->pe - m->ps);
       if ((h->flags & (FlagL|FlagS|FlagM)) == 0 && m->ps == m->pe)
               m->p = seprint(m->p, m->e, " ack");

       return 0;
}

Proto ttls =
{
       "ttls",
       nil,
       nil,
       p_seprint,
       p_mux, /* we need this to get the dump printed */
       "%lud",
       nil,
       defaultframer,
};