/*
 * IS-IS Rout(e)ing protocol - isis_pdu.c   
 *                             PDU processing
 *
 * Copyright (C) 2001,2002   Sampo Saaristo
 *                           Tampere University of Technology      
 *                           Institute of Communications Engineering
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public Licenseas published by the Free 
 * Software Foundation; either version 2 of the License, or (at your option) 
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
 * more details.

 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <stdio.h>
#include <string.h>
#include <zebra.h>
#include <net/ethernet.h>

#include "memory.h"
#include "thread.h"
#include "linklist.h"
#include "log.h"
#include "stream.h"
#include "vty.h"
#include "hash.c"
#include "prefix.h"
#include "if.h"

#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_tlv.h"
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/iso_checksum.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"

extern struct thread_master *master;
extern struct isis *isis;

#define ISIS_MINIMUM_FIXED_HDR_LEN 15
#define ISIS_MIN_PDU_LEN           13 /* partial seqnum pdu with id_len=2 */

#ifndef PNBBY
#define PNBBY 8
#endif /* PNBBY */

/* Utility mask array. */
static u_char maskbit[] = 
{
  0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
};

/*
 * HELPER FUNCS
 */

/*
 * Compares two sets of area addresses
 */
static int 
area_match (struct list *left, struct list *right)
{
  struct area_addr *addr1, *addr2;
  struct listnode *node1, *node2;

  LIST_LOOP (left, addr1, node1) {
    LIST_LOOP (right, addr2, node2) {
      if (addr1->addr_len == addr2->addr_len && 
        !memcmp (addr1->area_addr, addr2->area_addr, (int)addr1->addr_len))
        return 1; /* match */
    }
  }

  return 0; /* mismatch */
}

/*
 * Check if ip2 is in the ip1's network (function like Prefix.h:prefix_match() )
 * param ip1            the IS interface ip address structure
 * param ip2            the IIH's ip address
 * return  0            the IIH's IP is not in the IS's subnetwork
 *         1            the IIH's IP is in the IS's subnetwork
 */
int
ip_same_subnet  (struct prefix_ipv4 *ip1, struct in_addr *ip2)
{
  u_char *addr1, *addr2;
  int shift, offset;
  int len;
    
  addr1 = (u_char *) &ip1->prefix.s_addr;
  addr2 = (u_char *) &ip2->s_addr;
  len = ip1->prefixlen;

  shift = len % PNBBY;
  offset = len / PNBBY;

  while (offset--) {
    if (addr1[offset] != addr2[offset]) {
      return 0;
    }
  }

  if (shift) {
    if (maskbit[shift] & (addr1[offset] ^ addr2[offset])) {
      return 0;
    }
  }
    
 return 1; /* match  */
}


/*
 * Compares two set of ip addresses
 * param left     the local interface's ip addresses
 * param right    the iih interface's ip address
 * return         0   no match;
 *                1   match;
 */
static int 
ip_match (struct list *left, struct list *right)
{
  struct prefix_ipv4 *ip1;
  struct in_addr *ip2;
  struct listnode *node1, *node2;

  LIST_LOOP (left, ip1, node1) {
    LIST_LOOP (right, ip2, node2) {
      if (ip_same_subnet(ip1, ip2)) {
        return 1;  /* match */
      }
    }
  
  }
  return 0;
}

/*
 * Checks whether we should accept a PDU of given level 
 */
static int
accept_level (int level, int circuit_t)
{
  int retval = ((circuit_t & level) == level); /* simple approach */

  return retval;
}

int 
authentication_check (struct isis_passwd *one, struct isis_passwd *theother)
{
  if (one->type != theother->type) {
    zlog_warn ("Unsupported authentication type %d", theother->type );
    return 1; /* Auth fail (different authentication types)*/
  }
  switch (one->type) {
  case ISIS_PASSWD_TYPE_CLEARTXT:
    if (one->len != theother->len)
      return 1; /* Auth fail () - passwd len mismatch */
    return memcmp (one->passwd, theother->passwd, one->len);
    break;
  default:
    zlog_warn ("Unsupported authentication type");
    break;
  }
  return 0; /* Auth pass */ 
}

/*
 * Processing helper functions
 */
void
tlvs_to_adj_nlpids (struct tlvs *tlvs, struct isis_adjacency *adj) 
{
  int i;
  struct nlpids *tlv_nlpids;

  if (tlvs->nlpids) {

    tlv_nlpids = tlvs->nlpids;

    adj->nlpids.count = tlv_nlpids->count;

    for (i=0;i<tlv_nlpids->count;i++) {
       adj->nlpids.nlpids[i] = tlv_nlpids->nlpids[i];
    }
  }
}

void  
del_ip_addr (void *val)
{
  XFREE (MTYPE_ISIS_TMP, val);
}

void
tlvs_to_adj_ipv4_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) 
{
  struct listnode *node;
  struct in_addr *ipv4_addr, *malloced;

  if (adj->ipv4_addrs) {
    adj->ipv4_addrs->del = del_ip_addr;
    list_delete (adj->ipv4_addrs);
  }
  adj->ipv4_addrs = list_new ();
  if (tlvs->ipv4_addrs) {
    LIST_LOOP (tlvs->ipv4_addrs, ipv4_addr, node) {
      malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in_addr));
      memcpy (malloced, ipv4_addr, sizeof (struct in_addr));
      listnode_add (adj->ipv4_addrs, malloced);
    }
  }
}

#ifdef HAVE_IPV6
void
tlvs_to_adj_ipv6_addrs (struct tlvs *tlvs, struct isis_adjacency *adj) 
{
  struct listnode *node;
  struct in6_addr *ipv6_addr, *malloced;

  if (adj->ipv6_addrs) {
    adj->ipv6_addrs->del = del_ip_addr;
    list_delete (adj->ipv6_addrs);
  }
  adj->ipv6_addrs = list_new ();
  if (tlvs->ipv6_addrs) {
    LIST_LOOP (tlvs->ipv6_addrs, ipv6_addr, node) {
      malloced = XMALLOC (MTYPE_ISIS_TMP, sizeof (struct in6_addr));
      memcpy (malloced, ipv6_addr, sizeof (struct in6_addr));
      listnode_add (adj->ipv6_addrs, malloced);
    }
  }

}
#endif /* HAVE_IPV6 */



/*
 *  RECEIVE SIDE                           
 */

/*
 * Process P2P IIH
 * ISO - 10589
 * Section 8.2.5 - Receiving point-to-point IIH PDUs
 *
 */
static int
process_p2p_hello (struct isis_circuit *circuit)
{
  int retval = ISIS_OK;
  struct isis_p2p_hello_hdr *hdr;
  struct isis_adjacency *adj;
  u_int32_t expected = 0, found;
  struct tlvs tlvs;

  if ((stream_get_endp (circuit->rcv_stream) - 
       stream_get_getp (circuit->rcv_stream)) <
      ISIS_P2PHELLO_HDRLEN) {
    zlog_warn ("Packet too short");
    return ISIS_WARNING;
  }

  /* 8.2.5.1 PDU acceptance tests */

  /* 8.2.5.1 a) external domain untrue */
  /* FIXME: not useful at all?         */

  /* 8.2.5.1 b) ID Length mismatch */
  /* checked at the handle_pdu     */

  /* 8.2.5.2 IIH PDU Processing */

  /* 8.2.5.2 a) 1) Maximum Area Addresses */
  /* Already checked, and can also be ommited */

  /*
   * Get the header
   */
  hdr = (struct isis_p2p_hello_hdr*) STREAM_PNT(circuit->rcv_stream);
  circuit->rcv_stream->getp += ISIS_P2PHELLO_HDRLEN;

  /*  hdr.circuit_t = stream_getc (stream);
      stream_get (hdr.source_id, stream, ISIS_SYS_ID_LEN);
      hdr.hold_time = stream_getw (stream);
      hdr.pdu_len   = stream_getw (stream);
      hdr.local_id  = stream_getc (stream); */

  /*
   * My interpertation of the ISO, if no adj exists we will create one for 
   * the circuit
   */

  if (isis->debugs  & DEBUG_ADJ_PACKETS) {
     zlog_info("ISIS-Adj (%s): Rcvd P2P IIH from (%s), cir type %s,"
	       " cir id %02d, length %d",
	       circuit->area->area_tag, circuit->interface->name, 
	       circuit_t2string(circuit->circuit_is_type),
	       circuit->circuit_id,ntohs(hdr->pdu_len));
  }

  adj = circuit->u.p2p.neighbor;
  if ( !adj ) {
    adj = isis_new_adj (hdr->source_id,"      ", 0, circuit);
    if (adj == NULL)
      return ISIS_ERROR;
    circuit->u.p2p.neighbor = adj;
    isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL);
    adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
  }

  /* 8.2.6 Monitoring point-to-point adjacencies */
  adj->hold_time = ntohs (hdr->hold_time);
  adj->last_upd  = time (NULL);

  /*
   * Lets get the TLVS now
   */
  expected |= TLVFLAG_AREA_ADDRS;
  expected |= TLVFLAG_AUTH_INFO;
  expected |= TLVFLAG_NLPID;
  expected |= TLVFLAG_IPV4_ADDR;
  expected |= TLVFLAG_IPV6_ADDR;

  retval = parse_tlvs (circuit->area->area_tag,
		       STREAM_PNT (circuit->rcv_stream),
		       ntohs (hdr->pdu_len) - ISIS_P2PHELLO_HDRLEN 
		       - ISIS_FIXED_HDR_LEN,
		       &expected,
		       &found,
		       &tlvs);

  if (retval > ISIS_WARNING) {
    free_tlvs (&tlvs);
    return retval;
  };

  /* 8.2.5.1 c) Authentication */
  if (circuit->passwd.type) {
    if (!(found & TLVFLAG_AUTH_INFO) || 
	authentication_check (&circuit->passwd, &tlvs.auth_info)) {
      isis_event_auth_failure (circuit->area->area_tag, 
			       "P2P hello authentication failure", 
			       hdr->source_id);
      return ISIS_OK;
    }
  }

  /* we do this now because the adj may not survive till the end... */

  /* we need to copy addresses to the adj */
  tlvs_to_adj_ipv4_addrs (&tlvs,adj);

#ifdef HAVE_IPV6
  tlvs_to_adj_ipv6_addrs (&tlvs,adj);
#endif /* HAVE_IPV6 */

  /* lets take care of the expiry */
  THREAD_TIMER_OFF(adj->t_expire);
  THREAD_TIMER_ON(master, adj->t_expire, isis_adj_expire, adj,
                                    (long)adj->hold_time);

  /* 8.2.5.2 a) a match was detected */
  if (area_match (circuit->area->area_addrs, tlvs.area_addrs)) {
    /* 8.2.5.2 a) 2) If the system is L1 - table 5 */
    if (circuit->area->is_type == IS_LEVEL_1) {
      switch (hdr->circuit_t) {
      case IS_LEVEL_1:
      case IS_LEVEL_1_AND_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (4) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (5) adj usage level 1 */
          adj->adj_usage = ISIS_ADJ_LEVEL1;
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
          ; /* accept */
        }
        break;
      case IS_LEVEL_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (7) reject - wrong system type event */
          zlog_warn ("wrongSystemType");
          return ISIS_WARNING; /* Reject */
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
          /* (6) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        }
        break;
      }
    }

    /* 8.2.5.2 a) 3) If the system is L1L2 - table 6 */
    if (circuit->area->is_type == IS_LEVEL_1_AND_2) {
      switch (hdr->circuit_t) {
      case IS_LEVEL_1:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (6) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (7) adj usage level 1 */
          adj->adj_usage = ISIS_ADJ_LEVEL1;
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
          ; /* accept */
        } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
                   (adj->adj_usage == ISIS_ADJ_LEVEL2)) {
          /* (8) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        }
        break;
      case IS_LEVEL_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (6) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (9) adj usage level 2 */
          adj->adj_usage = ISIS_ADJ_LEVEL2;
        } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
                   (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)) {
          /* (8) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
          ; /* Accept */
        }
        break;
      case IS_LEVEL_1_AND_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (6) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (10) adj usage level 1 */
          adj->adj_usage = ISIS_ADJ_LEVEL1AND2;
        } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1) ||
                   (adj->adj_usage == ISIS_ADJ_LEVEL2)) {
          /* (8) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) {
          ; /* Accept */
        }
        break;
      }
    }

    /* 8.2.5.2 a) 4) If the system is L2 - table 7 */
    if (circuit->area->is_type == IS_LEVEL_2) {
      switch (hdr->circuit_t) {
      case IS_LEVEL_1:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (5) reject - wrong system type event */
          zlog_warn ("wrongSystemType");
          return ISIS_WARNING; /* Reject */
        } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
                   (adj->adj_usage == ISIS_ADJ_LEVEL2)) {
          /* (6) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        }
        break;
      case IS_LEVEL_1_AND_2:
      case IS_LEVEL_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (7) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (8) adj usage level 2 */
          adj->adj_usage = ISIS_ADJ_LEVEL2;
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) {
          /* (6) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
          ; /* Accept */
        }
        break;
      }
    }
  }
  /* 8.2.5.2 b) if no match was detected */
  else
  {
    if (circuit->area->is_type == IS_LEVEL_1) {
      /* 8.2.5.2 b) 1) is_type L1 and adj is not up */
      if (adj->adj_state != ISIS_ADJ_UP) {
        isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
      /* 8.2.5.2 b) 2)is_type L1 and adj is up */
      } else {
        isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Down - Area Mismatch");
      }
    }
    /* 8.2.5.2 b 3 If the system is L2 or L1L2 - table 8 */
    else
    {
      switch (hdr->circuit_t) {
      case IS_LEVEL_1:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (6) reject - Area Mismatch event */
          zlog_warn ("AreaMismatch");
          return ISIS_WARNING; /* Reject */
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
          /* (7) down - area mismatch */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");

        } else if ((adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
                   (adj->adj_usage == ISIS_ADJ_LEVEL2)) {
          /* (7) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        }
        break;
      case IS_LEVEL_1_AND_2:
      case IS_LEVEL_2:
        if (adj->adj_state != ISIS_ADJ_UP) {
          /* (8) adj state up */
          isis_adj_state_change (adj, ISIS_ADJ_UP, NULL);
          /* (9) adj usage level 2 */
          adj->adj_usage = ISIS_ADJ_LEVEL2;
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
          /* (7) down - wrong system */
          isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) {
          if (hdr->circuit_t == IS_LEVEL_2) {
            /* (7) down - wrong system */
            isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System");
          } else {
            /* (7) down - area mismatch */
            isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch");
          }
        } else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
          ; /* Accept */
        }
        break;
      }
    }
  }
  /* 8.2.5.2 c) if the action was up - comparing circuit IDs */
  /* FIXME - Missing parts */


  /* some of my own understanding of the ISO, why the heck does
   * it not say what should I change the system_type to...
   */
  switch (adj->adj_usage) {
    case ISIS_ADJ_LEVEL1:
      adj->sys_type = ISIS_SYSTYPE_L1_IS;
      break;
    case ISIS_ADJ_LEVEL2:
      adj->sys_type = ISIS_SYSTYPE_L2_IS;
      break;
    case ISIS_ADJ_LEVEL1AND2:
      adj->sys_type = ISIS_SYSTYPE_L2_IS;
      break;
    case ISIS_ADJ_NONE:
      adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
      break;
  }

  adj->circuit_t = hdr->circuit_t;
  adj->level = hdr->circuit_t;

  free_tlvs (&tlvs);

  return retval;
}


/*
 * Process IS-IS LAN Level 1/2 Hello PDU
 */
static int 
process_lan_hello (int level, struct isis_circuit *circuit, u_char *ssnpa)
{
  int retval = ISIS_OK;
  struct isis_lan_hello_hdr hdr;
  struct isis_adjacency *adj;
  u_int32_t expected = 0, found;
  struct tlvs tlvs;
  u_char *snpa;
  struct listnode *node;

  if ((stream_get_endp (circuit->rcv_stream) - 
       stream_get_getp (circuit->rcv_stream)) < ISIS_LANHELLO_HDRLEN) {
    zlog_warn ("Packet too short");
    return ISIS_WARNING;
  }

  if (circuit->ext_domain) {
    zlog_info ("level %d LAN Hello received over circuit with "
	       "externalDomain = true", level);
    return ISIS_WARNING;
  }

  if (!accept_level (level, circuit->circuit_is_type)) {
    if (isis->debugs & DEBUG_ADJ_PACKETS) {
      zlog_info ("ISIS-Adj (%s): Interface level mismatch, %s",
                 circuit->area->area_tag, circuit->interface->name);
    }
    return ISIS_WARNING;
  }

#if 0
  /* Cisco's debug message compatability */
  if (!accept_level (level, circuit->area->is_type)) {
    if (isis->debugs & DEBUG_ADJ_PACKETS) {
      zlog_info ("ISIS-Adj (%s): is type mismatch",
                 circuit->area->area_tag);
    }
    return ISIS_WARNING;
  }
#endif
  /*
   * Fill the header
   */
  hdr.circuit_t = stream_getc (circuit->rcv_stream);
  stream_get (hdr.source_id, circuit->rcv_stream, ISIS_SYS_ID_LEN);
  hdr.hold_time = stream_getw (circuit->rcv_stream);
  hdr.pdu_len   = stream_getw (circuit->rcv_stream);
  hdr.prio      = stream_getc (circuit->rcv_stream);
  stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1);

  if (hdr.circuit_t != IS_LEVEL_1 && hdr.circuit_t != IS_LEVEL_2 &&
      hdr.circuit_t != IS_LEVEL_1_AND_2 ) {
    zlog_warn ("Level %d LAN Hello with Circuit Type %d", level, 
	       hdr.circuit_t);
    return ISIS_ERROR;
  }
  /*
   * Then get the tlvs
   */
  expected |= TLVFLAG_AUTH_INFO;
  expected |= TLVFLAG_AREA_ADDRS;
  expected |= TLVFLAG_LAN_NEIGHS;
  expected |= TLVFLAG_NLPID;
  expected |= TLVFLAG_IPV4_ADDR;
  expected |= TLVFLAG_IPV6_ADDR;

  retval = parse_tlvs (circuit->area->area_tag,
                       STREAM_PNT (circuit->rcv_stream),
                       hdr.pdu_len - ISIS_LANHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
                       &expected,
                       &found,
                       &tlvs);

  if (retval > ISIS_WARNING) {
    zlog_warn ("parse_tlvs() failed");
    goto out;
  }

  if (!(found & TLVFLAG_AREA_ADDRS)) {
    zlog_warn ("No Area addresses TLV in Level %d LAN IS to IS hello", level);
    retval = ISIS_WARNING;
    goto out;
  }

  if (circuit->passwd.type) {
    if (!(found & TLVFLAG_AUTH_INFO) || 
	authentication_check (&circuit->passwd, &tlvs.auth_info)) {
      isis_event_auth_failure (circuit->area->area_tag, 
			       "LAN hello authentication failure", 
        hdr.source_id);
      retval = ISIS_WARNING;
      goto out;
    }
  }

  /*
   * Accept the level 1 adjacency only if a match between local and
   * remote area addresses is found
   */
  if (level == 1 && !area_match (circuit->area->area_addrs, tlvs.area_addrs)) {
    if (isis->debugs & DEBUG_ADJ_PACKETS) {
      zlog_info ("ISIS-Adj (%s): Area mismatch, level %d IIH on %s",
                 circuit->area->area_tag, level,circuit->interface->name);
    }
    retval = ISIS_OK;
    goto out;
  }

  /* 
   * it's own IIH PDU - discard silently 
   */ 
  if (!memcmp (circuit->u.bc.snpa, ssnpa, ETH_ALEN)) {
    zlog_info ("ISIS-Adj (%s): it's own IIH PDU - discarded", 
	       circuit->area->area_tag);

    retval = ISIS_OK;
    goto out;
  }

  /*
   * check if it's own interface ip match iih ip addrs
   */
  if (!(found & TLVFLAG_IPV4_ADDR) || !ip_match(circuit->ip_addrs, tlvs.ipv4_addrs)) {
    zlog_info("ISIS-Adj: No usable IP interface addresses in LAN IIH from %s\n",
   		circuit->interface->name);
    retval = ISIS_WARNING;
    goto out;
  }


  adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]);
  if (!adj) {
    /*
     * Do as in 8.4.2.5
     */
    adj = isis_new_adj (hdr.source_id, ssnpa, level, circuit);
    if (adj == NULL)
      retval = ISIS_ERROR;
      goto out;

    adj->level = level;
    isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL);

    if (level == 1) {
      adj->sys_type = ISIS_SYSTYPE_L1_IS;
    } else {
      adj->sys_type = ISIS_SYSTYPE_L2_IS;
    }
    list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
    isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
                               circuit->u.bc.lan_neighs[level - 1]); 
  }

  switch (level) {
  case 1 :
    if (memcmp(circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1)) {
      thread_add_event (master, isis_event_dis_status_change, circuit, 0);
      memcpy (&circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
    }
    break;
  case 2 : 
    if (memcmp (circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1)) {
      thread_add_event (master, isis_event_dis_status_change, circuit, 0);
      memcpy (&circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
    }
    break;
  }

#if 0
 /* Old solution: believe the lan-header always
  */
  if (level == 1) {
    memcpy(circuit->u.bc.l1_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
  } else if (level == 2) {
    memcpy(circuit->u.bc.l2_desig_is, hdr.lan_id, ISIS_SYS_ID_LEN + 1);
  }
#endif

  adj->hold_time = hdr.hold_time;
  adj->last_upd  = time (NULL);
  adj->prio[level-1] = hdr.prio;

  memcpy (adj->lanid, hdr.lan_id, ISIS_SYS_ID_LEN + 1);

  /* which protocol are spoken ??? */
  if (found & TLVFLAG_NLPID) 
    tlvs_to_adj_nlpids (&tlvs, adj);

  /* we need to copy addresses to the adj */
  if (found & TLVFLAG_IPV4_ADDR) 
    tlvs_to_adj_ipv4_addrs (&tlvs, adj);

#ifdef HAVE_IPV6
  if (found & TLVFLAG_IPV6_ADDR) 
    tlvs_to_adj_ipv6_addrs (&tlvs, adj);
#endif /* HAVE_IPV6 */

  adj->circuit_t = hdr.circuit_t;

  /* lets take care of the expiry */
  THREAD_TIMER_OFF(adj->t_expire);
  THREAD_TIMER_ON(master, adj->t_expire, isis_adj_expire, adj,
                                    (long)adj->hold_time);

  /*
   * If the snpa for this circuit is found from LAN Neighbours TLV
   * we have two-way communication -> adjacency can be put to state "up"
   */

  if (found & TLVFLAG_LAN_NEIGHS) {
    if (adj->adj_state != ISIS_ADJ_UP) {
      LIST_LOOP (tlvs.lan_neighs, snpa, node)
        if (!memcmp (snpa, circuit->u.bc.snpa, ETH_ALEN)) {
          isis_adj_state_change (adj, ISIS_ADJ_UP, 
                                 "own SNPA found in LAN Neighbours TLV");
        }
    }
  }

 out:
  /* DEBUG_ADJ_PACKETS */
  if (isis->debugs & DEBUG_ADJ_PACKETS) {
    /* FIXME: is this place right? fix missing info */
    zlog_info ("ISIS-Adj (%s): Rcvd L%d LAN IIH from %s on %s, cirType %s, "
               "cirID %u, length %ld",
	       circuit->area->area_tag, 
               level,snpa_print(ssnpa), circuit->interface->name,
               circuit_t2string(circuit->circuit_is_type),
               circuit->circuit_id,
               stream_get_endp (circuit->rcv_stream));
  }


  free_tlvs (&tlvs);

  return retval;
}

/*
 * Process Level 1/2 Link State
 * ISO - 10589
 * Section 7.3.15.1 - Action on receipt of a link state PDU
 */ 
static int 
process_lsp (int level, struct isis_circuit *circuit, u_char *ssnpa)
{
  struct isis_link_state_hdr *hdr;
  struct isis_adjacency *adj = NULL;
  struct isis_lsp *lsp, *lsp0 = NULL;
  int retval = ISIS_OK, comp = 0;
  u_char lspid[ISIS_SYS_ID_LEN + 2];
  struct isis_passwd *passwd;

  /* Sanity check - FIXME: move to correct place */
  if ((stream_get_endp (circuit->rcv_stream) - 
       stream_get_getp (circuit->rcv_stream)) < ISIS_LSP_HDR_LEN ) {
    zlog_warn ("Packet too short");
    return ISIS_WARNING;
  }

  /* Reference the header   */
  hdr = (struct isis_link_state_hdr*)STREAM_PNT (circuit->rcv_stream);

  if (isis->debugs & DEBUG_UPDATE_PACKETS) {
    zlog_info ("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, "
               "lifetime %us, len %lu, on %s",
	       circuit->area->area_tag,
	       level, 
               rawlspid_print(hdr->lsp_id),
	       ntohl(hdr->seq_num),
	       ntohs(hdr->checksum),
	       ntohs(hdr->rem_lifetime),
	       circuit->rcv_stream->endp,
               circuit->interface->name);
  }

  assert (ntohs (hdr->pdu_len) > ISIS_LSP_HDR_LEN);

  /* Checksum sanity check - FIXME: move to correct place */
  /* 12 = sysid+pdu+remtime */
  if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4, 
      ntohs (hdr->pdu_len) - 12, &hdr->checksum)) {
    zlog_info ("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
	       circuit->area->area_tag,
	       rawlspid_print (hdr->lsp_id),
	       ntohs(hdr->checksum));

    return ISIS_WARNING;
  }

  /* 7.3.15.1 a) 1 - external domain circuit will discard lsps */
  if (circuit->ext_domain) {
    zlog_info ("ISIS-Upd (%s): LSP %s received at level %d over circuit with "
               "externalDomain = true",
	       circuit->area->area_tag,
	       rawlspid_print (hdr->lsp_id),	       
	       level);

    return ISIS_WARNING;
  }

  /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
  if (!accept_level (level, circuit->circuit_is_type)) {
    zlog_info ("ISIS-Upd (%s): LSP %s received at level %d over circuit of"
               " type %s", 
	       circuit->area->area_tag,
	       rawlspid_print(hdr->lsp_id),	
               level,
	       circuit_t2string (circuit->circuit_is_type));

    return ISIS_WARNING;
  }

  /* 7.3.15.1 a) 4 - need to make sure IDLength matches */

  /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use 3 */

  /* 7.3.15.1 a) 7 - password check */
  (level == ISIS_LEVEL1) ? (passwd = &circuit->area->area_passwd) :
    (passwd = &circuit->area->domain_passwd);
  if (passwd->type) {
    if (isis_lsp_authinfo_check (circuit->rcv_stream, circuit->area,
				 ntohs (hdr->pdu_len), passwd)) {
      isis_event_auth_failure (circuit->area->area_tag,
			       "LSP authentication failure",
			       hdr->lsp_id);
      return ISIS_WARNING;
    }
  }
  /* Find the LSP in our database and compare it to this Link State header */
  lsp = lsp_search (hdr->lsp_id, circuit->area->lspdb[level - 1]);
  if (lsp)
    comp = lsp_compare (circuit->area->area_tag, lsp, hdr->seq_num, 
                        hdr->checksum, hdr->rem_lifetime);
  if (lsp && (lsp->own_lsp 
#ifdef TOPOLOGY_GENERATE
              || lsp->from_topology
#endif /* TOPOLOGY_GENERATE */
              ))
    goto dontcheckadj;

  /* 7.3.15.1 a) 6 - Must check that we have an adjacency of the same level  */
  /* for broadcast circuits, snpa should be compared */
  /* FIXME : Point To Point */

  if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
    adj = isis_adj_lookup_snpa (ssnpa, circuit->u.bc.adjdb[level - 1]);
    if (!adj) {
      zlog_info ("(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, "
		 "lifetime %us on %s",
		 circuit->area->area_tag,
		 rawlspid_print (hdr->lsp_id),
		 ntohl (hdr->seq_num),
		 ntohs (hdr->checksum),
		 ntohs (hdr->rem_lifetime), 
		 circuit->interface->name);
      return ISIS_WARNING; /* Silently discard */
    }
  }

  /* for non broadcast, we just need to find same level adj */
  else {
    /* If no adj, or no sharing of level */
    if (!circuit->u.p2p.neighbor) {
      return ISIS_OK; /* Silently discard */
    } else {
      if (((level == 1) && 
           (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL2)) ||
          ((level == 2) && 
           (circuit->u.p2p.neighbor->adj_usage == ISIS_ADJ_LEVEL1)))
      return ISIS_WARNING; /* Silently discard */
    }
  }
 dontcheckadj:
  /* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented  */

  /* 7.3.15.1 a) 8 - Passwords for level 2 - not implemented  */

  /* 7.3.15.1 a) 9 - OriginatingLSPBufferSize - not implemented  FIXME: do it*/


  /* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4*/
  if (hdr->rem_lifetime == 0) {
    if (!lsp) {
      /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't save */
      /* only needed on explicit update, eg - p2p */
      if (circuit->circ_type == CIRCUIT_T_P2P)
        ack_lsp (hdr, circuit, level);
      return retval; /* FIXME: do we need a purge? */
    } else {
      if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN )) {
        /* LSP by some other system -> do 7.3.16.4 b) */
        /* 7.3.16.4 b) 1)  */
        if (comp == LSP_NEWER) {
          lsp_update (lsp, hdr, circuit->rcv_stream, circuit->area);
          /* ii */
          ISIS_FLAGS_SET_ALL (lsp->SRMflags);   
          /* iii */
          ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
          /* v */
          ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); /* FIXME: OTHER than c */
          /* iv */
          if (circuit->circ_type != CIRCUIT_T_BROADCAST)
            ISIS_SET_FLAG(lsp->SSNflags, circuit);

        } /* 7.3.16.4 b) 2) */
        else if (comp == LSP_EQUAL) {
          /* i */
          ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
          /* ii*/
          if (circuit->circ_type != CIRCUIT_T_BROADCAST)
            ISIS_SET_FLAG(lsp->SSNflags, circuit);
        }  /* 7.3.16.4 b) 3) */
        else {
          ISIS_SET_FLAG(lsp->SRMflags, circuit);
          ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
        }
      } else {
        /* our own LSP -> 7.3.16.4 c) */
        if (LSP_PSEUDO_ID(lsp->lsp_header->lsp_id) != circuit->circuit_id ||
            (LSP_PSEUDO_ID(lsp->lsp_header->lsp_id) == circuit->circuit_id &&
             circuit->u.bc.is_dr[level - 1] == 1) ) { 
          lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1);
          zlog_info ("LSP LEN: %d", ntohs (lsp->lsp_header->pdu_len));
          iso_csum_create (STREAM_DATA (lsp->pdu) + 12, 
                           ntohs (lsp->lsp_header->pdu_len) - 12, 12);
          ISIS_FLAGS_SET_ALL (lsp->SRMflags);
          zlog_info ("ISIS-Upd (%s): (1) re-originating LSP %s new seq 0x%08x",
                     circuit->area->area_tag,
                     rawlspid_print (hdr->lsp_id),
                     ntohl (lsp->lsp_header->seq_num));
          lsp->lsp_header->rem_lifetime = htons (isis_jitter 
                                                 (circuit->area->
                                                  max_lsp_lifetime[level-1],
                                                  MAX_AGE_JITTER));

        } else {
          /* Got purge for own pseudo-lsp, and we are not DR  */
            lsp_purge_dr (lsp->lsp_header->lsp_id, circuit, level);
        } 
      }
    }
    return retval;
  }
  /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a 
   * purge */
  if (memcmp (hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN ) == 0) {
    if (!lsp) {
    /* 7.3.16.4: initiate a purge */
      lsp_purge_non_exist (hdr, circuit->area);
      return ISIS_OK;
    }
    /* 7.3.15.1 d) - If this is our own lsp and we have it */

    /* In 7.3.16.1, If an Intermediate system R somewhere in the domain
     * has information that the current sequence number for source S is
     * "greater" than that held by S, ... */

    else if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num)) {
      /* 7.3.16.1  */
      lsp->lsp_header->seq_num = htonl (ntohl (hdr->seq_num) + 1);

      iso_csum_create (STREAM_DATA (lsp->pdu) + 12, 
                       ntohs(lsp->lsp_header->pdu_len) - 12, 12);

      ISIS_FLAGS_SET_ALL (lsp->SRMflags);
      zlog_info ("ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08x",
                 circuit->area->area_tag,
                 rawlspid_print (hdr->lsp_id),
                 ntohl (lsp->lsp_header->seq_num));
      lsp->lsp_header->rem_lifetime = htons (isis_jitter 
                                             (circuit->
                                              area->max_lsp_lifetime[level-1],
                                              MAX_AGE_JITTER));

    }
  } else {
  /* 7.3.15.1 e) - This lsp originated on another system */

    /* 7.3.15.1 e) 1) LSP newer than the one in db or no LSP in db */
    if ((!lsp || comp == LSP_NEWER)){
      /* i */
      if (lsp) {
#ifdef EXTREME_DEBUG
        zlog_info ("level %d number is - %ld", level, 
                   circuit->area->lspdb[level-1]->dict_nodecount);
#endif /* EXTREME DEBUG */
        lsp_search_and_destroy (hdr->lsp_id, circuit->area->lspdb[level-1]);
        /* exists, so we overwrite */
#ifdef EXTREME_DEBUG
        zlog_info ("level %d number is - %ld",level, 
                   circuit->area->lspdb[level-1]->dict_nodecount);
#endif /* EXTREME DEBUG */
      }
      /*
       * If this lsp is a frag, need to see if we have zero lsp present
       */
      if (LSP_FRAGMENT (hdr->lsp_id) != 0) {
        memcpy (lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1);
        LSP_FRAGMENT (lspid) = 0;
        lsp0 = lsp_search (lspid, circuit->area->lspdb[level - 1]);
        if (!lsp0) {
          zlog_info ("Got lsp frag, while zero lsp not database");
          return ISIS_OK;
        }
      }
      lsp = lsp_new_from_stream_ptr (circuit->rcv_stream, ntohs (hdr->pdu_len),
                                     lsp0, circuit->area);
      lsp->level = level;
      lsp->adj = adj;
      lsp_insert (lsp, circuit->area->lspdb[level-1]);
      /* ii */
      ISIS_FLAGS_SET_ALL (lsp->SRMflags);
      /* iii */
      ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);

      /* iv */
      if (circuit->circ_type != CIRCUIT_T_BROADCAST)
        ISIS_SET_FLAG (lsp->SSNflags, circuit);
      /* FIXME: v) */
    }
    /* 7.3.15.1 e) 2) LSP equal to the one in db */
    else if (comp == LSP_EQUAL) {
      ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
      lsp_update (lsp, hdr, circuit->rcv_stream, circuit->area);
      if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
        ISIS_SET_FLAG (lsp->SSNflags, circuit);
      }
    }
    /* 7.3.15.1 e) 3) LSP older than the one in db */
    else {
      ISIS_SET_FLAG(lsp->SRMflags, circuit);
      ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
    }
  }
  if (lsp)
    lsp->adj = adj;
  return retval;
}

/*
 * Process Sequence Numbers
 * ISO - 10589
 * Section 7.3.15.2 - Action on receipt of a sequence numbers PDU
 */

int
process_snp (int snp_type, int level, struct isis_circuit *circuit, 
             u_char *ssnpa)
{
  int retval = ISIS_OK;
  int cmp, own_lsp;
  char typechar = ' ';
  int len;
  struct isis_adjacency *adj;
  struct isis_complete_seqnum_hdr *chdr = NULL;
  struct isis_partial_seqnum_hdr *phdr = NULL;
  uint32_t found = 0, expected = 0;
  struct isis_lsp *lsp;
  struct lsp_entry *entry;
  struct listnode *node,*node2;
  struct tlvs tlvs;
  struct list *lsp_list = NULL;
  struct isis_passwd *passwd;

  if (snp_type == ISIS_SNP_CSNP_FLAG) {
  /* getting the header info */
    typechar = 'C';
    chdr = (struct isis_complete_seqnum_hdr*)STREAM_PNT(circuit->rcv_stream);
    circuit->rcv_stream->getp += ISIS_CSNP_HDRLEN;
    len = ntohs(chdr->pdu_len);
    if (len < ISIS_CSNP_HDRLEN) {
      zlog_warn ("Received a CSNP with bogus length!");
      return ISIS_OK;
    }
  } else {
    typechar = 'P';
    phdr = (struct isis_partial_seqnum_hdr*)STREAM_PNT(circuit->rcv_stream);
    circuit->rcv_stream->getp += ISIS_PSNP_HDRLEN;
    len = ntohs(phdr->pdu_len);
    if (len < ISIS_PSNP_HDRLEN) {
      zlog_warn ("Received a CSNP with bogus length!");
      return ISIS_OK;
    }
  }

  /* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */
  if (circuit->ext_domain) {

    zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
	       "skipping: circuit externalDomain = true",
	       circuit->area->area_tag,
	       level,
	       typechar,
	       circuit->interface->name);

    return ISIS_OK;
  }

  /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */
  if (!accept_level (level, circuit->circuit_is_type)) {

    zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
	       "skipping: circuit type %s does not match level %d",
	       circuit->area->area_tag,
	       level, 
               typechar,
	       circuit->interface->name,
	       circuit_t2string (circuit->circuit_is_type),
	       level);

    return ISIS_OK;
  }

  /* 7.3.15.2 a) 4 - not applicable for CSNP  only PSNPs on broadcast */
  if ((snp_type == ISIS_SNP_PSNP_FLAG) && 
      (circuit->circ_type == CIRCUIT_T_BROADCAST)) {
    if (!circuit->u.bc.is_dr[level-1]) {

      zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s, "
		 "skipping: we are not the DIS",
		 circuit->area->area_tag,
                 level,
		 typechar,
		 snpa_print(ssnpa),
		 circuit->interface->name);

      return ISIS_OK;
    }
  }

  /* 7.3.15.2 a) 5 - need to make sure IDLength matches - already checked */

  /* 7.3.15.2 a) 6 - maximum area match, can be ommited since we only use 3
   * - already checked */

  /* 7.3.15.2 a) 7 - Must check that we have an adjacency of the same level  */
  /* for broadcast circuits, snpa should be compared */
  /* FIXME : Do we need to check SNPA? */
  if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
    if (snp_type == ISIS_SNP_CSNP_FLAG) {
      adj = isis_adj_lookup (chdr->source_id, circuit->u.bc.adjdb[level - 1]);
    } else {
      /* a psnp on a broadcast, how lovely of Juniper :) */
      adj = isis_adj_lookup (phdr->source_id, circuit->u.bc.adjdb[level - 1]);
    }
    if (!adj)
      return ISIS_OK; /* Silently discard */
  } else {
    if (!circuit->u.p2p.neighbor)
      return ISIS_OK; /* Silently discard */
  }

  /* 7.3.15.2 a) 8 - Passwords for level 1 - not implemented  */

  /* 7.3.15.2 a) 9 - Passwords for level 2 - not implemented  */

  memset (&tlvs, 0, sizeof (struct tlvs));

  /* parse the SNP */
  expected |= TLVFLAG_LSP_ENTRIES;
  expected |= TLVFLAG_AUTH_INFO;
  retval = parse_tlvs (circuit->area->area_tag,
		       STREAM_PNT(circuit->rcv_stream),
		       len - circuit->rcv_stream->getp,
		       &expected,
		       &found,
		       &tlvs);

  if (retval > ISIS_WARNING) {
    zlog_warn ("something went very wrong processing SNP");
    free_tlvs (&tlvs);
    return retval;
  }

  (level == 1) ? (passwd = &circuit->area->area_passwd) :
		  (passwd = &circuit->area->domain_passwd);
  if (passwd->type) {
    if (!(found & TLVFLAG_AUTH_INFO) ||
	authentication_check (passwd, &tlvs.auth_info)) {
      isis_event_auth_failure (circuit->area->area_tag, "SNP authentication"
			       " failure", phdr ?
			       phdr->source_id : chdr->source_id);
      return ISIS_OK;
    } 
  }

  /* debug isis snp-packets */
  if (isis->debugs & DEBUG_SNP_PACKETS) {
    zlog_info ("ISIS-Snp (%s): Rcvd L%d %cSNP from %s on %s", 
               circuit->area->area_tag,
	       level,
	       typechar,
	       snpa_print(ssnpa),
               circuit->interface->name);
    if (tlvs.lsp_entries) {
      LIST_LOOP (tlvs.lsp_entries,entry,node) {
        zlog_info("ISIS-Snp (%s):         %cSNP entry %s, seq 0x%08x,"
                  " cksum 0x%04x, lifetime %us", 
                  circuit->area->area_tag,
                  typechar, 
                  rawlspid_print (entry->lsp_id),
                  ntohl (entry->seq_num),
                  ntohs (entry->checksum),
                  ntohs (entry->rem_lifetime));
      }
    }
  }

  /* 7.3.15.2 b) Actions on LSP_ENTRIES reported */
  if (tlvs.lsp_entries) {
    LIST_LOOP (tlvs.lsp_entries, entry, node) {
      lsp = lsp_search (entry->lsp_id, circuit->area->lspdb[level - 1]);
      own_lsp = !memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
      if (lsp) {
        /* 7.3.15.2 b) 1) is this LSP newer */
        cmp = lsp_compare (circuit->area->area_tag, lsp, entry->seq_num, 
                           entry->checksum, entry->rem_lifetime);
        /* 7.3.15.2 b) 2) if it equals, clear SRM on p2p */
        if (cmp == LSP_EQUAL) {
          if (circuit->circ_type != CIRCUIT_T_BROADCAST) 
            ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);
          /* 7.3.15.2 b) 3) if it is older, clear SSN and set SRM */
        } else if (cmp == LSP_OLDER) {
          ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
        ISIS_SET_FLAG (lsp->SRMflags, circuit);
        } else {
          /* 7.3.15.2 b) 4) if it is newer, set SSN and clear SRM on p2p*/
          if (own_lsp) {
            lsp_inc_seqnum (lsp, ntohl (entry->seq_num));
            ISIS_SET_FLAG (lsp->SRMflags, circuit);
          } else {
            ISIS_SET_FLAG (lsp->SSNflags, circuit);
            if (circuit->circ_type != CIRCUIT_T_BROADCAST)
            ISIS_CLEAR_FLAG (lsp->SRMflags, circuit); 
          }
        }
      } else {
        /* 7.3.15.2 b) 5) if it was not found, and all of those are not 0, 
         * insert it and set SSN on it */
        if (entry->rem_lifetime && entry->checksum && entry->seq_num && 
            memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) {
          lsp = lsp_new (entry->lsp_id, ntohs (entry->rem_lifetime),
                       0, 0, entry->checksum, level);
          lsp_insert (lsp, circuit->area->lspdb[level - 1]);
          ISIS_SET_FLAG (lsp->SSNflags, circuit);
        }
      }
    }
  }

  /* 7.3.15.2 c) on CSNP set SRM for all in range which were not reported */
  if (snp_type == ISIS_SNP_CSNP_FLAG) {
    /*
     * Build a list from our own LSP db bounded with start_ and stop_lsp_id
     */
    lsp_list = list_new ();
    lsp_build_list_nonzero_ht (chdr->start_lsp_id, chdr->stop_lsp_id, 
                               lsp_list, circuit->area->lspdb[level - 1]);

    /* Fixme: Find a better solution */
    if (tlvs.lsp_entries) {
      LIST_LOOP (tlvs.lsp_entries, entry, node) {
        LIST_LOOP (lsp_list, lsp, node2) {
          if (lsp_id_cmp (lsp->lsp_header->lsp_id, entry->lsp_id) == 0) {
            list_delete_node (lsp_list, node2);
          break;
          }
        }
      }
    }
    /* on remaining LSPs we set SRM (neighbor knew not of) */
    LIST_LOOP (lsp_list, lsp, node2) {
      ISIS_SET_FLAG (lsp->SRMflags, circuit);
    }
    /* lets free it */
    list_free (lsp_list);
  }

  free_tlvs (&tlvs);
  return retval;
}

int
process_csnp (int level, struct isis_circuit *circuit, u_char *ssnpa)
{

  /* Sanity check - FIXME: move to correct place */
  if ((stream_get_endp (circuit->rcv_stream) - 
       stream_get_getp (circuit->rcv_stream)) < ISIS_CSNP_HDRLEN) {
    zlog_warn ("Packet too short ( < %d)",  ISIS_CSNP_HDRLEN);
    return ISIS_WARNING;
  }

  return process_snp (ISIS_SNP_CSNP_FLAG, level, circuit, ssnpa);
}

int 
process_psnp (int level, struct isis_circuit *circuit, u_char *ssnpa)
{

  if ((stream_get_endp (circuit->rcv_stream) - 
       stream_get_getp (circuit->rcv_stream)) < ISIS_PSNP_HDRLEN) {
    zlog_warn ("Packet too short");
    return ISIS_WARNING;
  }

  return process_snp (ISIS_SNP_PSNP_FLAG, level, circuit, ssnpa);
}



/*
 * Process ISH
 * ISO - 10589
 * Section 8.2.2 - Receiving ISH PDUs by an intermediate system
 * FIXME: sample packet dump, need to figure 0x81 - looks like NLPid
            0x82	0x15	0x01	0x00	0x04	0x01	0x2c	0x59
            0x38	0x08	0x47	0x00	0x01	0x00	0x02	0x00
          	0x03	0x00	0x81	0x01	0xcc
 */
int
process_is_hello (struct isis_circuit *circuit)
{
  struct isis_adjacency *adj;
  int retval = ISIS_OK;
  u_char neigh_len;
  u_char *sysid;

  /* In this point in time we are not yet able to handle is_hellos
   * on lan - Sorry juniper...
   */
  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
    return retval;

  neigh_len = stream_getc (circuit->rcv_stream);
  sysid = STREAM_PNT(circuit->rcv_stream) + neigh_len - 1 - ISIS_SYS_ID_LEN;
  adj = circuit->u.p2p.neighbor;
  if (!adj) {
    /* 8.2.2 */
    adj = isis_new_adj (sysid, "      ", 0, circuit);
    if (adj == NULL)
      return ISIS_ERROR;

    isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL);
    adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
    circuit->u.p2p.neighbor = adj;
  }
  /* 8.2.2 a)*/
  if ((adj->adj_state == ISIS_ADJ_UP) && memcmp (adj->sysid,sysid,
                                                 ISIS_SYS_ID_LEN)) {
    /* 8.2.2 a) 1) FIXME: adjStateChange(down) event */
    /* 8.2.2 a) 2) delete the adj */
    XFREE (MTYPE_ISIS_ADJACENCY, adj);
    /* 8.2.2 a) 3) create a new adj */
    adj = isis_new_adj (sysid, "      ", 0, circuit);
    if (adj == NULL)
      return ISIS_ERROR;

    /* 8.2.2 a) 3) i */
    isis_adj_state_change (adj, ISIS_ADJ_INITIALIZING, NULL);
    /* 8.2.2 a) 3) ii */
    adj->sys_type = ISIS_SYSTYPE_UNKNOWN;
    /* 8.2.2 a) 4) quite meaningless */
  }
  /* 8.2.2 b) ignore on condition */
  if ((adj->adj_state == ISIS_ADJ_INITIALIZING) && 
      (adj->sys_type == ISIS_SYSTYPE_IS)) {
    /* do nothing */
  } else {
  /* 8.2.2 c) respond with a p2p IIH */
    send_hello (circuit, 1);
  }
  /* 8.2.2 d) type is IS */
    adj->sys_type = ISIS_SYSTYPE_IS;
  /* 8.2.2 e) FIXME: Circuit type of? */


  return retval;
}


/*
 * PDU Dispatcher
 */

int 
isis_handle_pdu (struct isis_circuit *circuit, u_char *ssnpa)
{

  struct isis_fixed_hdr *hdr;
  struct esis_fixed_hdr *esis_hdr;

  int retval=ISIS_OK;

  /*
   * Let's first read data from stream to the header
   */
  hdr = (struct isis_fixed_hdr*)STREAM_DATA(circuit->rcv_stream);

  if ((hdr->idrp != ISO10589_ISIS) && (hdr->idrp != ISO9542_ESIS)){
    zlog_warn ("Not an IS-IS or ES-IS packet IDRP=%02x", hdr->idrp);
    return ISIS_ERROR;
  }

  /* now we need to know if this is an ISO 9542 packet and
   * take real good care of it, waaa!
   */
  if (hdr->idrp == ISO9542_ESIS){
    esis_hdr = (struct esis_fixed_hdr*)STREAM_DATA(circuit->rcv_stream);
    stream_set_getp (circuit->rcv_stream, ESIS_FIXED_HDR_LEN);
    /* FIXME: Need to do some acceptence tests */
    /* example length... */
    switch (esis_hdr->pdu_type) {
      case ESH_PDU:
        /* FIXME */
        break;
      case ISH_PDU:
        zlog_info ("AN ISH PDU!!");
        retval = process_is_hello (circuit);
        break;
      default:
        return ISIS_ERROR;
      }
    return retval;
  } else {
    stream_set_getp (circuit->rcv_stream, ISIS_FIXED_HDR_LEN);
  }
  /*
   * and then process it
   */

  if (hdr->length < ISIS_MINIMUM_FIXED_HDR_LEN) {
    zlog_err ("Fixed header length = %d", hdr->length);
    return ISIS_ERROR;
  }

  if (hdr->version1 != 1) {
    zlog_warn ("Unsupported ISIS version %u", hdr->version1);
    return ISIS_WARNING;
  }
  /* either 6 or 0 */
  if ((hdr->id_len != 0) && (hdr->id_len != ISIS_SYS_ID_LEN))  { 
    zlog_err ("IDFieldLengthMismatch: ID Length field in a received PDU  %u, "
                      "while the parameter for this IS is %u", hdr->id_len,
                       ISIS_SYS_ID_LEN);
    return ISIS_ERROR;
  }

  if (hdr->version2 != 1) {
    zlog_warn ("Unsupported ISIS version %u", hdr->version2);
    return ISIS_WARNING;
  }
  /* either 3 or 0 */
  if ((hdr->max_area_addrs != 0) && (hdr->max_area_addrs != isis->max_area_addrs)) { 
    zlog_err ("maximumAreaAddressesMismatch: maximumAreaAdresses in a "
                      "received PDU %u while the parameter for this IS is %u",
                       hdr->max_area_addrs, isis->max_area_addrs);
    return ISIS_ERROR;
  }

  switch (hdr->pdu_type) {
  case L1_LAN_HELLO:
    retval = process_lan_hello (ISIS_LEVEL1, circuit, ssnpa);
    break;
  case L2_LAN_HELLO:
    retval = process_lan_hello (ISIS_LEVEL2, circuit, ssnpa);
    break;
  case P2P_HELLO:
    retval = process_p2p_hello (circuit);
    break;
  case L1_LINK_STATE:
    retval = process_lsp (ISIS_LEVEL1, circuit, ssnpa);
    break;
  case L2_LINK_STATE:
    retval = process_lsp (ISIS_LEVEL2, circuit, ssnpa);
    break;
  case L1_COMPLETE_SEQ_NUM:
    retval = process_csnp (ISIS_LEVEL1, circuit, ssnpa);
    break;
  case L2_COMPLETE_SEQ_NUM:
    retval = process_csnp (ISIS_LEVEL2, circuit, ssnpa);
    break;
  case L1_PARTIAL_SEQ_NUM:
    retval = process_psnp (ISIS_LEVEL1, circuit, ssnpa);
    break;
  case L2_PARTIAL_SEQ_NUM:
    retval = process_psnp (ISIS_LEVEL2, circuit, ssnpa);
    break;
  default:
    return ISIS_ERROR;
  }

  return retval;
}


#ifdef GNU_LINUX
int
isis_receive (struct thread *thread)
{

  struct isis_circuit *circuit;
  u_char ssnpa[ETH_ALEN];
  int retval;

  /*
   * Get the circuit 
   */
  circuit = THREAD_ARG (thread);
  assert (circuit);

  if (circuit->rcv_stream == NULL)
    circuit->rcv_stream = stream_new (ISO_MTU(circuit));
  else
    stream_reset (circuit->rcv_stream);

  retval = circuit->rx (circuit, ssnpa);
  circuit->t_read = NULL;  

  if (retval == ISIS_OK)
    retval = isis_handle_pdu (circuit, ssnpa);

  /* 
   * prepare for next packet. 
   */
  THREAD_READ_ON(master, circuit->t_read, isis_receive, circuit, circuit->fd);

  return retval;
}

#else
int
isis_receive (struct thread *thread)
{

  struct isis_circuit *circuit;
  u_char ssnpa[ETH_ALEN];
  int retval;

  /*
   * Get the circuit 
   */
  circuit = THREAD_ARG (thread);
  assert (circuit);

  circuit->t_read = NULL;  

  if (circuit->rcv_stream == NULL)
    circuit->rcv_stream = stream_new (ISO_MTU(circuit));
  else
    stream_reset (circuit->rcv_stream);

  retval = circuit->rx (circuit, ssnpa);

  if (retval == ISIS_OK)
    retval = isis_handle_pdu (circuit, ssnpa);

  /* 
   * prepare for next packet. 
   */
  circuit->t_read = thread_add_timer_msec (master, isis_receive, circuit, 
                                           listcount
                                           (circuit->area->circuit_list)*100);


  return retval;
}

#endif

 /* filling of the fixed isis header */
void
fill_fixed_hdr (struct isis_fixed_hdr *hdr, u_char pdu_type)
{
  memset (hdr, 0, sizeof (struct isis_fixed_hdr));

  hdr->idrp = ISO10589_ISIS;

  switch (pdu_type) {
  case L1_LAN_HELLO:
  case L2_LAN_HELLO:
    hdr->length = ISIS_LANHELLO_HDRLEN;
    break;
  case P2P_HELLO:
    hdr->length = ISIS_P2PHELLO_HDRLEN;
    break;
  case L1_LINK_STATE:
  case L2_LINK_STATE:
    hdr->length = ISIS_LSP_HDR_LEN;
    break;
  case L1_COMPLETE_SEQ_NUM:
  case L2_COMPLETE_SEQ_NUM:
    hdr->length = ISIS_CSNP_HDRLEN;
    break;
  case L1_PARTIAL_SEQ_NUM:
  case L2_PARTIAL_SEQ_NUM:
    hdr->length = ISIS_PSNP_HDRLEN;
    break;
  default:
    zlog_warn ("fill_fixed_hdr(): unknown pdu type %d", pdu_type);
    return;
  }
  hdr->length += ISIS_FIXED_HDR_LEN;
  hdr->pdu_type = pdu_type;
  hdr->version1 = 1;
  hdr->id_len = 0; /* ISIS_SYS_ID_LEN -  0==6 */
  hdr->version2 = 1;
  hdr->max_area_addrs = 0; /* isis->max_area_addrs -  0==3 */
}


/*
 * SEND SIDE                             
 */
void
fill_fixed_hdr_andstream (struct isis_fixed_hdr *hdr, u_char pdu_type,
		struct stream *stream)
{
  fill_fixed_hdr (hdr,pdu_type);

  stream_putc (stream, hdr->idrp);
  stream_putc (stream, hdr->length);
  stream_putc (stream, hdr->version1);
  stream_putc (stream, hdr->id_len);
  stream_putc (stream, hdr->pdu_type);
  stream_putc (stream, hdr->version2);
  stream_putc (stream, hdr->reserved);
  stream_putc (stream, hdr->max_area_addrs);

  return;
}


int
send_hello (struct isis_circuit *circuit, int level)
{
  struct isis_fixed_hdr fixed_hdr;
  struct isis_lan_hello_hdr hello_hdr;
  struct isis_p2p_hello_hdr p2p_hello_hdr;

  u_int32_t interval;
  unsigned long len_pointer, length;
  int retval;

  if (circuit->interface->mtu == 0) {
    zlog_warn ("circuit has zero MTU");
    return ISIS_WARNING;
  }

  if (!circuit->snd_stream)
    circuit->snd_stream = stream_new (ISO_MTU(circuit));
  else
    stream_reset (circuit->snd_stream);

  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
    if (level == 1)
      fill_fixed_hdr_andstream(&fixed_hdr, L1_LAN_HELLO, circuit->snd_stream);
    else
      fill_fixed_hdr_andstream(&fixed_hdr, L2_LAN_HELLO, circuit->snd_stream);
  else
      fill_fixed_hdr_andstream(&fixed_hdr, P2P_HELLO, circuit->snd_stream);

  /*
   * Fill LAN Level 1 or 2 Hello PDU header
   */
  memset (&hello_hdr, 0, sizeof (struct isis_lan_hello_hdr));
  interval = circuit->hello_multiplier[level - 1] * 
    circuit->hello_interval[level - 1];
  if (interval > USHRT_MAX)
    interval = USHRT_MAX;
  hello_hdr.circuit_t = circuit->circuit_is_type;
  memcpy (hello_hdr.source_id, isis->sysid, ISIS_SYS_ID_LEN);
  hello_hdr.hold_time = htons((u_int16_t)interval);

  hello_hdr.pdu_len   = 0;                   /* Update the PDU Length later */
  len_pointer = stream_get_putp (circuit->snd_stream) + 3 + ISIS_SYS_ID_LEN;   


  /* copy the shared part of the hello to the p2p hello if needed */
  if (circuit->circ_type == CIRCUIT_T_P2P) {
    memcpy (&p2p_hello_hdr, &hello_hdr, 5 + ISIS_SYS_ID_LEN);
    p2p_hello_hdr.local_id = circuit->circuit_id; 
    /* FIXME: need better understanding */
    stream_put  (circuit->snd_stream, &p2p_hello_hdr, ISIS_P2PHELLO_HDRLEN);
  } else {
    hello_hdr.prio = circuit->u.bc.priority[level - 1];
    if(level == 1 && circuit->u.bc.l1_desig_is) {
      memcpy(hello_hdr.lan_id, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
    } else if (level == 2 && circuit->u.bc.l2_desig_is){
      memcpy(hello_hdr.lan_id, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
    }
    stream_put  (circuit->snd_stream, &hello_hdr, ISIS_LANHELLO_HDRLEN);
  }

  /*
   * Then the variable length part 
   */
  /* add circuit password */
  if (circuit->passwd.type)
    if (tlv_add_authinfo (circuit->passwd.type, circuit->passwd.len,
			  circuit->passwd.passwd, circuit->snd_stream))
      return ISIS_WARNING;
  /*  Area Addresses TLV */
  assert (circuit->area);
  if (circuit->area->area_addrs && circuit->area->area_addrs->count > 0)
    if (tlv_add_area_addrs (circuit->area->area_addrs, circuit->snd_stream))
      return ISIS_WARNING;

  /*  LAN Neighbors TLV */
  if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
    if (level == 1 && circuit->u.bc.lan_neighs[0]->count > 0)
      if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[0], 
          circuit->snd_stream))
        return ISIS_WARNING;
    if (level == 2 && circuit->u.bc.lan_neighs[1]->count > 0)
      if (tlv_add_lan_neighs (circuit->u.bc.lan_neighs[1], 
          circuit->snd_stream))
        return ISIS_WARNING;
  }

  /* Protocols Supported TLV */
  if (circuit->nlpids.count > 0) 
    if (tlv_add_nlpid (&circuit->nlpids, circuit->snd_stream))
      return ISIS_WARNING;
  /* IP interface Address TLV */
  if (circuit->ip_router && circuit->ip_addrs && circuit->ip_addrs->count > 0)
    if (tlv_add_ip_addrs (circuit->ip_addrs, circuit->snd_stream))
      return ISIS_WARNING;

#ifdef HAVE_IPV6 
  /* IPv6 Interface Address TLV */
  if (circuit->ipv6_router && circuit->ipv6_link && 
      circuit->ipv6_link->count > 0)
    if (tlv_add_ipv6_addrs (circuit->ipv6_link, circuit->snd_stream))
      return ISIS_WARNING;
#endif /* HAVE_IPV6 */

  if (circuit->u.bc.pad_hellos)
    if (tlv_add_padding (circuit->snd_stream))
      return ISIS_WARNING;

  length = stream_get_putp (circuit->snd_stream);
  /* Update PDU length */
  stream_putw_at (circuit->snd_stream, len_pointer, (u_int16_t)length);

  retval = circuit->tx (circuit, level);
  if (retval)
    zlog_warn ("sending of LAN Level %d Hello failed", level);

  /* DEBUG_ADJ_PACKETS */
  if (isis->debugs & DEBUG_ADJ_PACKETS) {
    if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
      zlog_info ("ISIS-Adj (%s): Sent L%d LAN IIH on %s, length %ld",
                 circuit->area->area_tag, level, circuit->interface->name,
                 STREAM_SIZE(circuit->snd_stream));
    } else {
      zlog_info ("ISIS-Adj (%s): Sent P2P IIH on %s, length %ld",
                 circuit->area->area_tag, circuit->interface->name,
                 STREAM_SIZE(circuit->snd_stream));
    }
  }


  return retval;
}

int
send_lan_hello (struct isis_circuit *circuit, int level)
{
  return send_hello (circuit,level);
}

int
send_lan_l1_hello (struct thread *thread)
{

  struct isis_circuit *circuit;
  int retval;

  circuit = THREAD_ARG (thread);
  assert (circuit);
  circuit->u.bc.t_send_lan_hello[0] = NULL;

  if (circuit->u.bc.run_dr_elect[0])
    retval = isis_dr_elect (circuit, 1); 

  retval = send_lan_hello (circuit, 1);

  /* set next timer thread */
  THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[0], send_lan_l1_hello,
      circuit, isis_jitter (circuit->hello_interval[0], IIH_JITTER));

  return retval;
}

int
send_lan_l2_hello (struct thread *thread)
{
  struct isis_circuit *circuit;
  int retval;

  circuit = THREAD_ARG (thread);
  assert (circuit);
  circuit->u.bc.t_send_lan_hello[1] = NULL;

  if (circuit->u.bc.run_dr_elect[1])
    retval = isis_dr_elect (circuit, 2);

  retval = send_lan_hello (circuit, 2);

  /* set next timer thread*/
  THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[1], send_lan_l2_hello,
      circuit, isis_jitter (circuit->hello_interval[1], IIH_JITTER));

  return retval;
}

int
send_p2p_hello (struct thread *thread)
{
  struct isis_circuit *circuit;

  circuit = THREAD_ARG (thread);
  assert (circuit);
  circuit->u.p2p.t_send_p2p_hello = NULL;

  send_hello(circuit,1);

  /* set next timer thread*/
  THREAD_TIMER_ON(master, circuit->u.p2p.t_send_p2p_hello, send_p2p_hello,
      circuit, isis_jitter (circuit->hello_interval[1], IIH_JITTER));

  return ISIS_OK;
}

int
build_csnp (int level, u_char *start, u_char *stop, struct list *lsps, 
            struct isis_circuit *circuit)
{
  struct isis_fixed_hdr fixed_hdr;
  struct isis_passwd *passwd;
  int retval = ISIS_OK;
  unsigned long lenp;
  u_int16_t length;

  if (level ==1)
    fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM, 
                              circuit->snd_stream);
  else
    fill_fixed_hdr_andstream (&fixed_hdr, L2_COMPLETE_SEQ_NUM, 
                              circuit->snd_stream);

  /*
   * Fill Level 1 or 2 Complete Sequence Numbers header
   */

  lenp = stream_get_putp (circuit->snd_stream);
  stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */
  /* no need to send the source here, it is always us if we csnp */
  stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
  /* with zero circuit id - ref 9.10, 9.11 */
  stream_putc (circuit->snd_stream, 0x00);

  stream_put (circuit->snd_stream, start, ISIS_SYS_ID_LEN + 2);
  stream_put (circuit->snd_stream, stop, ISIS_SYS_ID_LEN + 2);

  /*
   * And TLVs
   */
  if (level == 1)
    passwd = &circuit->area->area_passwd;
  else
    passwd = &circuit->area->domain_passwd;

  if (passwd->type)
    retval = tlv_add_authinfo (passwd->type, passwd->len,
			       passwd->passwd, circuit->snd_stream);

  if (!retval && lsps) { 
    retval = tlv_add_lsp_entries (lsps, circuit->snd_stream);
  } 
  length = (u_int16_t)stream_get_putp (circuit->snd_stream);
  assert (length >= ISIS_CSNP_HDRLEN);
  /* Update PU length */
  stream_putw_at (circuit->snd_stream, lenp, length);

  return retval;
}

/*
 * FIXME: support multiple CSNPs
 */

int
send_csnp (struct isis_circuit *circuit, int level)
{
  int retval = ISIS_OK;
  u_char start[ISIS_SYS_ID_LEN + 2];
  u_char stop[ISIS_SYS_ID_LEN + 2];
  struct list *list = NULL;
  struct listnode *node;
  struct isis_lsp *lsp;

  memset (start,0x00, ISIS_SYS_ID_LEN + 2);
  memset (stop, 0xff, ISIS_SYS_ID_LEN + 2);

  if (circuit->area->lspdb[level-1] && 
      dict_count (circuit->area->lspdb[level-1]) > 0) {
    list = list_new ();
    lsp_build_list (start, stop, list, circuit->area->lspdb[level-1]);

    if (circuit->snd_stream == NULL)
      circuit->snd_stream = stream_new (ISO_MTU(circuit));
    else
      stream_reset (circuit->snd_stream);

    retval = build_csnp  (level, start, stop, list, circuit);

    if (isis->debugs & DEBUG_SNP_PACKETS) { 
      zlog_info ("ISIS-Snp (%s): Sent L%d CSNP on %s, length %ld",
                 circuit->area->area_tag, level, circuit->interface->name,
                 STREAM_SIZE(circuit->snd_stream));
      LIST_LOOP (list, lsp, node) {
        zlog_info("ISIS-Snp (%s):         CSNP entry %s, seq 0x%08x,"
                  " cksum 0x%04x, lifetime %us", 
                  circuit->area->area_tag,
                  rawlspid_print (lsp->lsp_header->lsp_id),
                  ntohl (lsp->lsp_header->seq_num),
                  ntohs (lsp->lsp_header->checksum),
                  ntohs (lsp->lsp_header->rem_lifetime));
      }
    }

    list_delete (list);

    if (retval == ISIS_OK)
      retval = circuit->tx (circuit, level);
  }
  return retval;
}

int
send_l1_csnp (struct thread *thread)
{
  struct isis_circuit *circuit;
  int retval = ISIS_OK;

  circuit = THREAD_ARG (thread);
  assert (circuit);

  circuit->t_send_csnp[0] = NULL;

  if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[0]) {
    send_csnp(circuit,1);
  }
  /* set next timer thread */
  THREAD_TIMER_ON(master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
      isis_jitter(circuit->csnp_interval[0], CSNP_JITTER));

  return retval;
}

int
send_l2_csnp (struct thread *thread)
{
  struct isis_circuit *circuit;
  int retval = ISIS_OK;

  circuit = THREAD_ARG (thread);
  assert (circuit);

  circuit->t_send_csnp[1] = NULL;

  if (circuit->circ_type == CIRCUIT_T_BROADCAST && circuit->u.bc.is_dr[1]) {
    send_csnp(circuit,2);
  }
  /* set next timer thread */
  THREAD_TIMER_ON(master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
      isis_jitter(circuit->csnp_interval[1], CSNP_JITTER));

  return retval;
}

int
build_psnp (int level, struct isis_circuit *circuit, struct list *lsps)
{
  struct isis_fixed_hdr fixed_hdr;
  unsigned long lenp;
  u_int16_t length;
  int retval = 0;
  struct isis_lsp *lsp;
  struct isis_passwd *passwd;
  struct listnode *node;

  if (level == 1)
    fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, 
                              circuit->snd_stream);
  else
    fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM,
                              circuit->snd_stream);

  /*
   * Fill Level 1 or 2 Partial Sequence Numbers header
   */
  lenp = stream_get_putp (circuit->snd_stream);
  stream_putw (circuit->snd_stream, 0); /* PDU length - when we know it */
  stream_put (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
  stream_putc (circuit->snd_stream, circuit->idx);

  /*
   * And TLVs
   */

  if (level == 1)
    passwd = &circuit->area->area_passwd;
  else
    passwd = &circuit->area->domain_passwd;

  if (passwd->type)
    retval = tlv_add_authinfo (passwd->type, passwd->len,
			       passwd->passwd, circuit->snd_stream);

  if (!retval && lsps) { 
    retval = tlv_add_lsp_entries (lsps, circuit->snd_stream);
  }

  if (isis->debugs & DEBUG_SNP_PACKETS) {
    LIST_LOOP (lsps, lsp, node) {
      zlog_info("ISIS-Snp (%s):         PSNP entry %s, seq 0x%08x,"
                " cksum 0x%04x, lifetime %us", 
                circuit->area->area_tag,
                rawlspid_print (lsp->lsp_header->lsp_id),
                ntohl (lsp->lsp_header->seq_num),
                ntohs (lsp->lsp_header->checksum),
                ntohs (lsp->lsp_header->rem_lifetime));
    }
  }

  length = (u_int16_t)stream_get_putp (circuit->snd_stream);
  assert (length >= ISIS_PSNP_HDRLEN);
  /* Update PDU length */
  stream_putw_at (circuit->snd_stream, lenp, length);

  return ISIS_OK;
}

/*
 *  7.3.15.4 action on expiration of partial SNP interval
 *  level 1
 */
int
send_psnp (int level, struct isis_circuit *circuit)
{
  int retval = ISIS_OK;
  struct isis_lsp *lsp;
  struct list *list = NULL;
  struct listnode *node;

  if ((circuit->circ_type == CIRCUIT_T_BROADCAST && 
       !circuit->u.bc.is_dr[level - 1]) ||
      circuit->circ_type != CIRCUIT_T_BROADCAST) {

    if (circuit->area->lspdb[level-1] && 
        dict_count (circuit->area->lspdb[level-1]) > 0) {
      list = list_new ();
      lsp_build_list_ssn (circuit, list, circuit->area->lspdb[level-1]);

      if (listcount(list) > 0) {
        if (circuit->snd_stream == NULL)
          circuit->snd_stream = stream_new (ISO_MTU(circuit));
        else
          stream_reset (circuit->snd_stream);


        if (isis->debugs & DEBUG_SNP_PACKETS) 
          zlog_info ("ISIS-Snp (%s): Sent L%d PSNP on %s, length %ld",
                     circuit->area->area_tag, level, circuit->interface->name,
                     STREAM_SIZE(circuit->snd_stream));

        retval = build_psnp (level, circuit, list);
        if (retval == ISIS_OK)
          retval = circuit->tx (circuit, level);

        if (retval == ISIS_OK) {
          /*
           * sending succeeded, we can clear SSN flags of this circuit
           * for the LSPs in list
           */
          for (node = listhead (list); node; nextnode(node)) {
            lsp = getdata (node);
            ISIS_CLEAR_FLAG (lsp->SSNflags, circuit);
          }
        }
      }
      list_delete (list);
    }
  }

  return retval;
}

int
send_l1_psnp (struct thread *thread)
{

  struct isis_circuit *circuit;
  int retval = ISIS_OK;

  circuit = THREAD_ARG (thread);
  assert (circuit);

  circuit->t_send_psnp[0] = NULL;

  send_psnp (1, circuit);
  /* set next timer thread */
  THREAD_TIMER_ON(master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
      isis_jitter(circuit->psnp_interval[0], PSNP_JITTER));

  return retval;
}

/*
 *  7.3.15.4 action on expiration of partial SNP interval
 *  level 2
 */
int
send_l2_psnp (struct thread *thread)
{

  struct isis_circuit *circuit;
  int retval = ISIS_OK;

  circuit = THREAD_ARG (thread);
  assert (circuit);

  circuit->t_send_psnp[1] = NULL;

  send_psnp (2, circuit);

  /* set next timer thread */
  THREAD_TIMER_ON(master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
      isis_jitter(circuit->psnp_interval[1], PSNP_JITTER));

  return retval;
}


void
build_link_state (struct isis_lsp *lsp, struct isis_circuit *circuit,
                  struct stream *stream)
{
  unsigned long length;

  stream_put  (stream, lsp->pdu, ntohs(lsp->lsp_header->pdu_len));
  length = stream_get_putp (stream); 

  return;
}


/*
 * ISO 10589 - 7.3.14.3
 */
int
send_lsp (struct thread *thread)
{
  struct isis_circuit *circuit;
  struct isis_lsp *lsp;
  struct listnode *node;
  int retval = 0;

  circuit = THREAD_ARG (thread);
  assert (circuit);

  if (circuit->state == C_STATE_UP) {
    node = listhead (circuit->lsp_queue);
    assert (node);

    lsp = getdata (node);

    /*
     * Do not send if levels do not match
     */
    if (!(lsp->level & circuit->circuit_is_type))
      goto dontsend;

    /*
     * Do not send if we do not have adjacencies in state up on the circuit
     */
    if (circuit->upadjcount[lsp->level - 1] == 0)
      goto dontsend;
    /* only send if it needs sending */
    if ((time(NULL) - lsp->last_sent) >= 
         circuit->area->lsp_gen_interval[lsp->level-1]) {

      if (isis->debugs & DEBUG_UPDATE_PACKETS) {
        zlog_info ("ISIS-Upd (%s): Sent L%d LSP %s, seq 0x%08x, cksum 0x%04x,"
                   " lifetime %us on %s",
                   circuit->area->area_tag,
		   lsp->level, 
                   rawlspid_print (lsp->lsp_header->lsp_id),
                   ntohl(lsp->lsp_header->seq_num),
		   ntohs(lsp->lsp_header->checksum),
                   ntohs(lsp->lsp_header->rem_lifetime), 
                   circuit->interface->name);
      }
      /* copy our lsp to the send buffer */
      circuit->snd_stream->getp = lsp->pdu->getp;
      circuit->snd_stream->putp = lsp->pdu->putp;
      circuit->snd_stream->endp = lsp->pdu->endp;
      memcpy (circuit->snd_stream->data, lsp->pdu->data, lsp->pdu->endp);

      retval = circuit->tx (circuit, lsp->level);

      /*
       * If the sending succeeded, we can del the lsp from circuits lsp_queue
       */
      if (retval == ISIS_OK) {
        list_delete_node (circuit->lsp_queue, node);

	/*
	 * On broadcast circuits also the SRMflag can be cleared
	 */
	if (circuit->circ_type == CIRCUIT_T_BROADCAST)
	  ISIS_CLEAR_FLAG (lsp->SRMflags, circuit);

	if (flags_any_set (lsp->SRMflags) == 0) {
	  /*
	   * need to remember when we were last sent
	   */
	  lsp->last_sent = time (NULL);
	}
      } else {
        zlog_info ("sending of level %d link state failed", lsp->level);
      }
    } else {
      /* my belief is that if it wasn't his time, the lsp can be removed
       * from the queue
       */
    dontsend:
      list_delete_node (circuit->lsp_queue, node);
    }
#if 0
    /*
     * If there are still LSPs send next one after lsp-interval (33 msecs)
     */
    if (listcount (circuit->lsp_queue) > 0)
      thread_add_timer (master, send_lsp, circuit,
                             1);
#endif
  }

  return retval;
} 

int
ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit, 
         int level)
{
  unsigned long lenp;
  int retval;
  u_int16_t length;
  struct isis_fixed_hdr fixed_hdr;

  if (!circuit->snd_stream)
    circuit->snd_stream = stream_new (ISO_MTU(circuit));
  else
    stream_reset (circuit->snd_stream);

//  fill_llc_hdr (stream);
  if (level == 1)
    fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM, 
                              circuit->snd_stream);
  else
    fill_fixed_hdr_andstream (&fixed_hdr, L2_PARTIAL_SEQ_NUM, 
                              circuit->snd_stream);


  lenp = stream_get_putp (circuit->snd_stream);
  stream_putw (circuit->snd_stream, 0); /* PDU length  */
  stream_put  (circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
  stream_putc (circuit->snd_stream, circuit->idx);
  stream_putc (circuit->snd_stream, 9); /* code */
  stream_putc (circuit->snd_stream, 16); /* len */

  stream_putw (circuit->snd_stream, ntohs(hdr->rem_lifetime));
  stream_put  (circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
  stream_putl (circuit->snd_stream, ntohl(hdr->seq_num));
  stream_putw (circuit->snd_stream, ntohs(hdr->checksum));

  length = (u_int16_t)stream_get_putp (circuit->snd_stream);
  /* Update PDU length */
  stream_putw_at (circuit->snd_stream, lenp, length);

  retval = circuit->tx (circuit, level);

  return retval;
}

#if 0
/*
 * ISH PDU Processing 
 */


  /*
   * Let's first check if the local and remote system have any common area
   * addresses 
   */
  if (area_match(tlvs.area_addrs, isis->man_area_addrs) == 0) {
    if (circuit->circuit_t == IS_LEVEL_2) {
      /* do as in table 8 (p. 40) */
      switch (circuit_type) {
      case IS_LEVEL_1:
	if (adj->adj_state != ISIS_ADJ_UP) {
	  /* Reject */
	  zlog_warn("areaMismatch");
	  retval = ISIS_WARNING;
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
	  isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch",
				 circuit->adjdb);
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2 || 
		   adj->adj_usage == ISIS_ADJ_LEVEL2) {
	  isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System",
				 circuit->adjdb);
	}
	break;
      case IS_LEVEL_2:
	if (adj->adj_state != ISIS_ADJ_UP) {
	  isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, circuit->adjdb);
	  adj->adj_usage = ISIS_ADJ_LEVEL2;
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL1 || 
	           adj->adj_usage == ISIS_ADJ_LEVEL1AND2) { 
	  isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System",
				 circuit->adjdb);
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
	    ; /* Accept */
	}
	break;
      case IS_LEVEL_1_AND_2:
	if (adj->adj_state != ISIS_ADJ_UP) {
	  isis_adj_state_change (adj, ISIS_ADJ_UP, NULL, circuit->adjdb);
	  adj->adj_usage = ISIS_ADJ_LEVEL2;
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL1) {
	  isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Wrong System",
				 circuit->adjdb);
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) { 
	  isis_adj_state_change (adj, ISIS_ADJ_DOWN, "Area Mismatch",
				 circuit->adjdb);
	} else if (adj->adj_usage == ISIS_ADJ_LEVEL2) {
	    ; /* Accept */
	}
	break;
      }
      goto mismatch;
    } else {
      isis_delete_adj (adj, circuit->adjdb);
      zlog_warn("areaMismatch");
      return ISIS_WARNING;
    }
  }

mismatch:
#endif




