ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
{
  int ws_pending, nl;
#ifdef EXACT_ADDRESS
  const char *begin;
#endif
  const char *ps;
  char comment[LONG_STRING], phrase[LONG_STRING];
  size_t phraselen = 0, commentlen = 0;
  ADDRESS *cur, *last = NULL;

  RFC822Error = 0;

  last = top;
  while (last && last->next)
    last = last->next;

  ws_pending = is_email_wsp (*s);
  if ((nl = mutt_strlen (s)))
    nl = s[nl - 1] == '\n';

  s = skip_email_wsp(s);
#ifdef EXACT_ADDRESS
  begin = s;
#endif
  while (*s)
  {
    if (*s == ',')
    {
      if (phraselen)
      {
	terminate_buffer (phrase, phraselen);
	add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
      }
      else if (commentlen && last && !last->personal)
      {
	terminate_buffer (comment, commentlen);
	last->personal = safe_strdup (comment);
      }

#ifdef EXACT_ADDRESS
      if (last && !last->val)
	last->val = mutt_substrdup (begin, s);
#endif
      commentlen = 0;
      phraselen = 0;
      s++;
#ifdef EXACT_ADDRESS
      begin = skip_email_wsp(s);
#endif
    }
    else if (*s == '(')
    {
      if (commentlen && commentlen < sizeof (comment) - 1)
	comment[commentlen++] = ' ';
      if ((ps = next_token (s, comment, &commentlen, sizeof (comment) - 1)) == NULL)
      {
	rfc822_free_address (&top);
	return NULL;
      }
      s = ps;
    }
    else if (*s == '"')
    {
      if (phraselen && phraselen < sizeof (phrase) - 1)
        phrase[phraselen++] = ' ';
      if ((ps = parse_quote (s + 1, phrase, &phraselen, sizeof (phrase) - 1)) == NULL)
      {
        rfc822_free_address (&top);
        return NULL;
      }
      s = ps;
    }
    else if (*s == '[')
    {
      if (phraselen && phraselen < sizeof (phrase) - 1 && ws_pending)
	phrase[phraselen++] = ' ';
      if (phraselen < sizeof (phrase) - 1)
        phrase[phraselen++] = '[';
      if ((ps = parse_literal (s + 1, phrase, &phraselen, sizeof (phrase) - 1)) == NULL)
      {
        rfc822_free_address (&top);
        return NULL;
      }
      s = ps;
    }
    else if (*s == ':')
    {
      cur = rfc822_new_address ();
      terminate_buffer (phrase, phraselen);
      cur->mailbox = safe_strdup (phrase);
      cur->group = 1;

      if (last)
	last->next = cur;
      else
	top = cur;
      last = cur;

#ifdef EXACT_ADDRESS
      last->val = mutt_substrdup (begin, s);
#endif

      phraselen = 0;
      commentlen = 0;
      s++;
#ifdef EXACT_ADDRESS
      begin = skip_email_wsp(s);
#endif
    }
    else if (*s == ';')
    {
      if (phraselen)
      {
	terminate_buffer (phrase, phraselen);
	add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
      }
      else if (commentlen && last && !last->personal)
      {
	terminate_buffer (comment, commentlen);
	last->personal = safe_strdup (comment);
      }
#ifdef EXACT_ADDRESS
      if (last && !last->val)
	last->val = mutt_substrdup (begin, s);
#endif

      /* add group terminator */
      cur = rfc822_new_address ();
      if (last)
      {
	last->next = cur;
	last = cur;
      }

      phraselen = 0;
      commentlen = 0;
#ifdef EXACT_ADDRESS
      begin = s;
#endif
      s++;
    }
    else if (*s == '<')
    {
      terminate_buffer (phrase, phraselen);
      cur = rfc822_new_address ();
      if (phraselen)
	cur->personal = safe_strdup (phrase);
      if ((ps = parse_route_addr (s + 1, comment, &commentlen, sizeof (comment) - 1, cur)) == NULL)
      {
	rfc822_free_address (&top);
	rfc822_free_address (&cur);
	return NULL;
      }

      if (last)
	last->next = cur;
      else
	top = cur;
      last = cur;

      phraselen = 0;
      commentlen = 0;
      s = ps;
    }
    else
    {
      if (phraselen && phraselen < sizeof (phrase) - 1 && ws_pending)
	phrase[phraselen++] = ' ';
      if ((ps = next_token (s, phrase, &phraselen, sizeof (phrase) - 1)) == NULL)
      {
	rfc822_free_address (&top);
	return NULL;
      }
      s = ps;
    }
    ws_pending = is_email_wsp(*s);
    s = skip_email_wsp(s);
  }

  if (phraselen)
  {
    terminate_buffer (phrase, phraselen);
    terminate_buffer (comment, commentlen);
    add_addrspec (&top, &last, phrase, comment, &commentlen, sizeof (comment) - 1);
  }
  else if (commentlen && last && !last->personal)
  {
    terminate_buffer (comment, commentlen);
    last->personal = safe_strdup (comment);
  }
#ifdef EXACT_ADDRESS
  if (last && !last->val)
    last->val = mutt_substrdup (begin, s - nl < begin ? begin : s - nl);
#endif

  return top;
}


static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int size1, len, fd_max; fd_set rfds; struct timeval tv; size1 = size; while (size > 0) { if (url_interrupt_cb()) return -EINTR; fd_max = s->fd; FD_ZERO(&rfds); FD_SET(s->fd, &rfds); tv.tv_sec = 0; tv.tv_usec = 100 * 1000; select(fd_max + 1, &rfds, NULL, NULL, &tv); #ifdef __BEOS__ len = recv(s->fd, buf, size, 0); #else len = read(s->fd, buf, size); #endif if (len < 0) { if (errno != EINTR && errno != EAGAIN) #ifdef __BEOS__ return errno; #else return -errno; #endif else continue; } else if (len == 0) { break; } size -= len; buf += len; } return size1 - size; }


static void clear_tfile_check_list(void)
{
	struct file *file;

	/* first clear the tfile_check_list */
	while (!list_empty(&tfile_check_list)) {
		file = list_first_entry(&tfile_check_list, struct file,
					f_tfile_llink);
		list_del_init(&file->f_tfile_llink);
	}
	INIT_LIST_HEAD(&tfile_check_list);
}


void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out) { ISAKBDState *isa = I8042(dev); KBDState *s = &isa->kbd; s->a20_out = a20_out; }


static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
{
	int error = 0;
	struct file *file = priv;
	struct eventpoll *ep = file->private_data;
	struct eventpoll *ep_tovisit;
	struct rb_node *rbp;
	struct epitem *epi;

	mutex_lock_nested(&ep->mtx, call_nests + 1);
	ep->visited = 1;
	list_add(&ep->visited_list_link, &visited_list);
	for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) {
		epi = rb_entry(rbp, struct epitem, rbn);
		if (unlikely(is_file_epoll(epi->ffd.file))) {
			ep_tovisit = epi->ffd.file->private_data;
			if (ep_tovisit->visited)
				continue;
			error = ep_call_nested(&poll_loop_ncalls,
					ep_loop_check_proc, epi->ffd.file,
					ep_tovisit, current);
			if (error != 0)
				break;
		} else {
			/*
			 * If we've reached a file that is not associated with
			 * an ep, then we need to check if the newly added
			 * links are going to add too many wakeup paths. We do
			 * this by adding it to the tfile_check_list, if it's
			 * not already there, and calling reverse_path_check()
			 * during ep_insert().
			 */
			if (list_empty(&epi->ffd.file->f_tfile_llink))
				list_add(&epi->ffd.file->f_tfile_llink,
					 &tfile_check_list);
		}
	}
	mutex_unlock(&ep->mtx);

	return error;
}


static int format_name(char *buf, int buf_len, int index) { const char *proto, *dir; char *orig_buf_dup = NULL, *mod_buf_dup = NULL; int ret = 0; if (!av_stristr(buf, "%v")) return ret; orig_buf_dup = av_strdup(buf); if (!orig_buf_dup) { ret = AVERROR(ENOMEM); goto fail; } if (replace_int_data_in_filename(buf, buf_len, orig_buf_dup, 'v', index) < 1) { ret = AVERROR(EINVAL); goto fail; } proto = avio_find_protocol_name(orig_buf_dup); dir = av_dirname(orig_buf_dup); /* if %v is present in the file's directory, create sub-directory */ if (av_stristr(dir, "%v") && proto && !strcmp(proto, "file")) { mod_buf_dup = av_strdup(buf); if (!mod_buf_dup) { ret = AVERROR(ENOMEM); goto fail; } dir = av_dirname(mod_buf_dup); if (mkdir_p(dir) == -1 && errno != EEXIST) { ret = AVERROR(errno); goto fail; } } fail: av_freep(&orig_buf_dup); av_freep(&mod_buf_dup); return ret; }


static void settings_changed(struct btd_adapter *adapter, uint32_t settings)
{
	uint32_t changed_mask;

	changed_mask = adapter->current_settings ^ settings;

	adapter->current_settings = settings;
	adapter->pending_settings &= ~changed_mask;

	DBG("Changed settings: 0x%08x", changed_mask);
	DBG("Pending settings: 0x%08x", adapter->pending_settings);

	if (changed_mask & MGMT_SETTING_POWERED) {
	        g_dbus_emit_property_changed(dbus_conn, adapter->path,
					ADAPTER_INTERFACE, "Powered");

		if (adapter->current_settings & MGMT_SETTING_POWERED) {
			adapter_start(adapter);
		} else {
			adapter_stop(adapter);

			if (powering_down) {
				adapter_remaining--;

				if (!adapter_remaining)
					btd_exit();
			}
		}
	}

	if ((changed_mask & MGMT_SETTING_LE) &&
				btd_adapter_get_powered(adapter) &&
				(adapter->current_settings & MGMT_SETTING_LE))
		trigger_passive_scanning(adapter);

	if (changed_mask & MGMT_SETTING_DISCOVERABLE) {
		g_dbus_emit_property_changed(dbus_conn, adapter->path,
					ADAPTER_INTERFACE, "Discoverable");
		store_adapter_info(adapter);
		btd_adv_manager_refresh(adapter->adv_manager);
	}

	if (changed_mask & MGMT_SETTING_BONDABLE) {
		g_dbus_emit_property_changed(dbus_conn, adapter->path,
					ADAPTER_INTERFACE, "Pairable");

		trigger_pairable_timeout(adapter);
	}
}


authzPrettyNormal(
	struct berval	*val,
	struct berval	*normalized,
	void		*ctx,
	int		normalize )
{
	struct berval	bv;
	int		rc = LDAP_INVALID_SYNTAX;
	LDAPURLDesc	*ludp = NULL;
	char		*lud_dn = NULL,
			*lud_filter = NULL;
	int		scope = -1;

	/*
	 * 1) <DN>
	 * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
	 * 3) dn.regex:<pattern>
	 * 4) u[.mech[/realm]]:<ID>
	 * 5) group[/<groupClass>[/<memberAttr>]]:<DN>
	 * 6) <URL>
	 */

	assert( val != NULL );
	assert( !BER_BVISNULL( val ) );

	/*
	 * 2) dn[.{exact|children|subtree|onelevel}]:{*|<DN>}
	 * 3) dn.regex:<pattern>
	 *
	 * <DN> must pass DN normalization
	 */
	if ( !strncasecmp( val->bv_val, "dn", STRLENOF( "dn" ) ) ) {
		struct berval	out = BER_BVNULL,
				prefix = BER_BVNULL;
		char		*ptr;

		bv.bv_val = val->bv_val + STRLENOF( "dn" );

		if ( bv.bv_val[ 0 ] == '.' ) {
			bv.bv_val++;

			if ( !strncasecmp( bv.bv_val, "exact:", STRLENOF( "exact:" ) ) ) {
				bv.bv_val += STRLENOF( "exact:" );
				scope = LDAP_X_SCOPE_EXACT;

			} else if ( !strncasecmp( bv.bv_val, "regex:", STRLENOF( "regex:" ) ) ) {
				bv.bv_val += STRLENOF( "regex:" );
				scope = LDAP_X_SCOPE_REGEX;

			} else if ( !strncasecmp( bv.bv_val, "children:", STRLENOF( "children:" ) ) ) {
				bv.bv_val += STRLENOF( "children:" );
				scope = LDAP_X_SCOPE_CHILDREN;

			} else if ( !strncasecmp( bv.bv_val, "subtree:", STRLENOF( "subtree:" ) ) ) {
				bv.bv_val += STRLENOF( "subtree:" );
				scope = LDAP_X_SCOPE_SUBTREE;

			} else if ( !strncasecmp( bv.bv_val, "onelevel:", STRLENOF( "onelevel:" ) ) ) {
				bv.bv_val += STRLENOF( "onelevel:" );
				scope = LDAP_X_SCOPE_ONELEVEL;

			} else {
				return LDAP_INVALID_SYNTAX;
			}

		} else {
			if ( bv.bv_val[ 0 ] != ':' ) {
				return LDAP_INVALID_SYNTAX;
			}
			scope = LDAP_X_SCOPE_EXACT;
			bv.bv_val++;
		}

		bv.bv_val += strspn( bv.bv_val, " " );
		/* jump here in case no type specification was present
		 * and uri was not an URI... HEADS-UP: assuming EXACT */
is_dn:		bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );

		/* a single '*' means any DN without using regexes */
		if ( ber_bvccmp( &bv, '*' ) ) {
			ber_str2bv_x( "dn:*", STRLENOF( "dn:*" ), 1, normalized, ctx );
			return LDAP_SUCCESS;
		}

		switch ( scope ) {
		case LDAP_X_SCOPE_EXACT:
		case LDAP_X_SCOPE_CHILDREN:
		case LDAP_X_SCOPE_SUBTREE:
		case LDAP_X_SCOPE_ONELEVEL:
			if ( normalize ) {
				rc = dnNormalize( 0, NULL, NULL, &bv, &out, ctx );
			} else {
				rc = dnPretty( NULL, &bv, &out, ctx );
			}
			if( rc != LDAP_SUCCESS ) {
				return LDAP_INVALID_SYNTAX;
			}
			break;

		case LDAP_X_SCOPE_REGEX:
			normalized->bv_len = STRLENOF( "dn.regex:" ) + bv.bv_len;
			normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );
			ptr = lutil_strcopy( normalized->bv_val, "dn.regex:" );
			ptr = lutil_strncopy( ptr, bv.bv_val, bv.bv_len );
			ptr[ 0 ] = '\0';
			return LDAP_SUCCESS;

		default:
			return LDAP_INVALID_SYNTAX;
		}

		/* prepare prefix */
		switch ( scope ) {
		case LDAP_X_SCOPE_EXACT:
			BER_BVSTR( &prefix, "dn:" );
			break;

		case LDAP_X_SCOPE_CHILDREN:
			BER_BVSTR( &prefix, "dn.children:" );
			break;

		case LDAP_X_SCOPE_SUBTREE:
			BER_BVSTR( &prefix, "dn.subtree:" );
			break;

		case LDAP_X_SCOPE_ONELEVEL:
			BER_BVSTR( &prefix, "dn.onelevel:" );
			break;

		default:
			assert( 0 );
			break;
		}

		normalized->bv_len = prefix.bv_len + out.bv_len;
		normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );

		ptr = lutil_strcopy( normalized->bv_val, prefix.bv_val );
		ptr = lutil_strncopy( ptr, out.bv_val, out.bv_len );
		ptr[ 0 ] = '\0';
		ber_memfree_x( out.bv_val, ctx );

		return LDAP_SUCCESS;

	/*
	 * 4) u[.mech[/realm]]:<ID>
	 */
	} else if ( ( val->bv_val[ 0 ] == 'u' || val->bv_val[ 0 ] == 'U' )
			&& ( val->bv_val[ 1 ] == ':'
				|| val->bv_val[ 1 ] == '/'
				|| val->bv_val[ 1 ] == '.' ) )
	{
		char		buf[ SLAP_LDAPDN_MAXLEN ];
		struct berval	id,
				user = BER_BVNULL,
				realm = BER_BVNULL,
				mech = BER_BVNULL;

		if ( sizeof( buf ) <= val->bv_len ) {
			return LDAP_INVALID_SYNTAX;
		}

		id.bv_len = val->bv_len;
		id.bv_val = buf;
		strncpy( buf, val->bv_val, sizeof( buf ) );

		rc = slap_parse_user( &id, &user, &realm, &mech );
		if ( rc != LDAP_SUCCESS ) {
			return LDAP_INVALID_SYNTAX;
		}

		ber_dupbv_x( normalized, val, ctx );

		return rc;

	/*
	 * 5) group[/groupClass[/memberAttr]]:<DN>
	 *
	 * <groupClass> defaults to "groupOfNames"
	 * <memberAttr> defaults to "member"
	 *
	 * <DN> must pass DN normalization
	 */
	} else if ( strncasecmp( val->bv_val, "group", STRLENOF( "group" ) ) == 0 )
	{
		struct berval	group_dn = BER_BVNULL,
				group_oc = BER_BVNULL,
				member_at = BER_BVNULL,
				out = BER_BVNULL;
		char		*ptr;

		bv.bv_val = val->bv_val + STRLENOF( "group" );
		bv.bv_len = val->bv_len - STRLENOF( "group" );
		group_dn.bv_val = ber_bvchr( &bv, ':' );
		if ( group_dn.bv_val == NULL ) {
			/* last chance: assume it's a(n exact) DN ... */
			bv.bv_val = val->bv_val;
			scope = LDAP_X_SCOPE_EXACT;
			goto is_dn;
		}

		/*
		 * FIXME: we assume that "member" and "groupOfNames"
		 * are present in schema...
		 */
		if ( bv.bv_val[ 0 ] == '/' ) {
			ObjectClass		*oc = NULL;

			group_oc.bv_val = &bv.bv_val[ 1 ];
			group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;

			member_at.bv_val = ber_bvchr( &group_oc, '/' );
			if ( member_at.bv_val ) {
				AttributeDescription	*ad = NULL;
				const char		*text = NULL;

				group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
				member_at.bv_val++;
				member_at.bv_len = group_dn.bv_val - member_at.bv_val;
				rc = slap_bv2ad( &member_at, &ad, &text );
				if ( rc != LDAP_SUCCESS ) {
					return rc;
				}

				member_at = ad->ad_cname;

			}

			oc = oc_bvfind( &group_oc );
			if ( oc == NULL ) {
				return LDAP_INVALID_SYNTAX;
			}

			group_oc = oc->soc_cname;
		}

		group_dn.bv_val++;
		group_dn.bv_len = val->bv_len - ( group_dn.bv_val - val->bv_val );

		if ( normalize ) {
			rc = dnNormalize( 0, NULL, NULL, &group_dn, &out, ctx );
		} else {
			rc = dnPretty( NULL, &group_dn, &out, ctx );
		}
		if ( rc != LDAP_SUCCESS ) {
			return rc;
		}

		normalized->bv_len = STRLENOF( "group" ":" ) + out.bv_len;
		if ( !BER_BVISNULL( &group_oc ) ) {
			normalized->bv_len += STRLENOF( "/" ) + group_oc.bv_len;
			if ( !BER_BVISNULL( &member_at ) ) {
				normalized->bv_len += STRLENOF( "/" ) + member_at.bv_len;
			}
		}

		normalized->bv_val = ber_memalloc_x( normalized->bv_len + 1, ctx );
		ptr = lutil_strcopy( normalized->bv_val, "group" );
		if ( !BER_BVISNULL( &group_oc ) ) {
			ptr[ 0 ] = '/';
			ptr++;
			ptr = lutil_strncopy( ptr, group_oc.bv_val, group_oc.bv_len );
			if ( !BER_BVISNULL( &member_at ) ) {
				ptr[ 0 ] = '/';
				ptr++;
				ptr = lutil_strncopy( ptr, member_at.bv_val, member_at.bv_len );
			}
		}
		ptr[ 0 ] = ':';
		ptr++;
		ptr = lutil_strncopy( ptr, out.bv_val, out.bv_len );
		ptr[ 0 ] = '\0';
		ber_memfree_x( out.bv_val, ctx );

		return rc;
	}

	/*
	 * ldap:///<base>??<scope>?<filter>
	 * <scope> ::= {base|one|subtree}
	 *
	 * <scope> defaults to "base"
	 * <base> must pass DN normalization
	 * <filter> must pass str2filter()
	 */
	rc = ldap_url_parse( val->bv_val, &ludp );
	switch ( rc ) {
	case LDAP_URL_SUCCESS:
		/* FIXME: the check is pedantic, but I think it's necessary,
		 * because people tend to use things like ldaps:// which
		 * gives the idea SSL is being used.  Maybe we could
		 * accept ldapi:// as well, but the point is that we use
		 * an URL as an easy means to define bits of a search with
		 * little parsing.
		 */
		if ( strcasecmp( ludp->lud_scheme, "ldap" ) != 0 ) {
			/*
			 * must be ldap:///
			 */
			rc = LDAP_INVALID_SYNTAX;
			goto done;
		}

		AC_MEMCPY( ludp->lud_scheme, "ldap", STRLENOF( "ldap" ) );
		break;

	case LDAP_URL_ERR_BADSCHEME:
		/*
		 * last chance: assume it's a(n exact) DN ...
		 *
		 * NOTE: must pass DN normalization
		 */
		ldap_free_urldesc( ludp );
		bv.bv_val = val->bv_val;
		scope = LDAP_X_SCOPE_EXACT;
		goto is_dn;

	default:
		rc = LDAP_INVALID_SYNTAX;
		goto done;
	}

	if ( ( ludp->lud_host && *ludp->lud_host )
		|| ludp->lud_attrs || ludp->lud_exts )
	{
		/* host part must be empty */
		/* attrs and extensions parts must be empty */
		rc = LDAP_INVALID_SYNTAX;
		goto done;
	}

	/* Grab the filter */
	if ( ludp->lud_filter ) {
		struct berval	filterstr;
		Filter		*f;

		lud_filter = ludp->lud_filter;

		f = str2filter( lud_filter );
		if ( f == NULL ) {
			rc = LDAP_INVALID_SYNTAX;
			goto done;
		}
		filter2bv( f, &filterstr );
		filter_free( f );
		if ( BER_BVISNULL( &filterstr ) ) {
			rc = LDAP_INVALID_SYNTAX;
			goto done;
		}

		ludp->lud_filter = filterstr.bv_val;
	}

	/* Grab the searchbase */
	assert( ludp->lud_dn != NULL );
	if ( ludp->lud_dn ) {
		struct berval	out = BER_BVNULL;

		lud_dn = ludp->lud_dn;

		ber_str2bv( lud_dn, 0, 0, &bv );
		if ( normalize ) {
			rc = dnNormalize( 0, NULL, NULL, &bv, &out, ctx );
		} else {
			rc = dnPretty( NULL, &bv, &out, ctx );
		}

		if ( rc != LDAP_SUCCESS ) {
			goto done;
		}

		ludp->lud_dn = out.bv_val;
	}

	ludp->lud_port = 0;
	normalized->bv_val = ldap_url_desc2str( ludp );
	if ( normalized->bv_val ) {
		normalized->bv_len = strlen( normalized->bv_val );

	} else {
		rc = LDAP_INVALID_SYNTAX;
	}

done:
	if ( lud_filter ) {
		if ( ludp->lud_filter != lud_filter ) {
			ber_memfree( ludp->lud_filter );
		}
		ludp->lud_filter = lud_filter;
	}

	if ( lud_dn ) {
		if ( ludp->lud_dn != lud_dn ) {
			ber_memfree( ludp->lud_dn );
		}
		ludp->lud_dn = lud_dn;
	}

	ldap_free_urldesc( ludp );

	return( rc );
}


static int cine_read_header ( AVFormatContext * avctx ) {
 AVIOContext * pb = avctx -> pb ;
 AVStream * st ;
 unsigned int version , compression , offImageHeader , offSetup , offImageOffsets , biBitCount , length , CFA ;
 int vflip ;
 char * description ;
 uint64_t i ;
 st = avformat_new_stream ( avctx , NULL ) ;
 if ( ! st ) return AVERROR ( ENOMEM ) ;
 st -> codecpar -> codec_type = AVMEDIA_TYPE_VIDEO ;
 st -> codecpar -> codec_id = AV_CODEC_ID_RAWVIDEO ;
 st -> codecpar -> codec_tag = 0 ;
 avio_skip ( pb , 4 ) ;
 compression = avio_rl16 ( pb ) ;
 version = avio_rl16 ( pb ) ;
 if ( version != 1 ) {
 avpriv_request_sample ( avctx , "unknown version %i" , version ) ;
 return AVERROR_INVALIDDATA ;
 }
 avio_skip ( pb , 12 ) ;
 st -> duration = avio_rl32 ( pb ) ;
 offImageHeader = avio_rl32 ( pb ) ;
 offSetup = avio_rl32 ( pb ) ;
 offImageOffsets = avio_rl32 ( pb ) ;
 avio_skip ( pb , 8 ) ;
 avio_seek ( pb , offImageHeader , SEEK_SET ) ;
 avio_skip ( pb , 4 ) ;
 st -> codecpar -> width = avio_rl32 ( pb ) ;
 st -> codecpar -> height = avio_rl32 ( pb ) ;
 if ( avio_rl16 ( pb ) != 1 ) return AVERROR_INVALIDDATA ;
 biBitCount = avio_rl16 ( pb ) ;
 if ( biBitCount != 8 && biBitCount != 16 && biBitCount != 24 && biBitCount != 48 ) {
 avpriv_request_sample ( avctx , "unsupported biBitCount %i" , biBitCount ) ;
 return AVERROR_INVALIDDATA ;
 }
 switch ( avio_rl32 ( pb ) ) {
 case BMP_RGB : vflip = 0 ;
 break ;
 case 0x100 : st -> codecpar -> codec_tag = MKTAG ( 'B' , 'I' , 'T' , 0 ) ;
 vflip = 1 ;
 break ;
 default : avpriv_request_sample ( avctx , "unknown bitmap compression" ) ;
 return AVERROR_INVALIDDATA ;
 }
 avio_skip ( pb , 4 ) ;
 avio_seek ( pb , offSetup , SEEK_SET ) ;
 avio_skip ( pb , 140 ) ;
 if ( avio_rl16 ( pb ) != 0x5453 ) return AVERROR_INVALIDDATA ;
 length = avio_rl16 ( pb ) ;
 if ( length < 0x163C ) {
 avpriv_request_sample ( avctx , "short SETUP header" ) ;
 return AVERROR_INVALIDDATA ;
 }
 avio_skip ( pb , 616 ) ;
 if ( ! avio_rl32 ( pb ) ^ vflip ) {
 st -> codecpar -> extradata = av_strdup ( "BottomUp" ) ;
 st -> codecpar -> extradata_size = 9 ;
 }
 avio_skip ( pb , 4 ) ;
 avpriv_set_pts_info ( st , 64 , 1 , avio_rl32 ( pb ) ) ;
 avio_skip ( pb , 20 ) ;
 set_metadata_int ( & st -> metadata , "camera_version" , avio_rl32 ( pb ) , 0 ) ;
 set_metadata_int ( & st -> metadata , "firmware_version" , avio_rl32 ( pb ) , 0 ) ;
 set_metadata_int ( & st -> metadata , "software_version" , avio_rl32 ( pb ) , 0 ) ;
 set_metadata_int ( & st -> metadata , "recording_timezone" , avio_rl32 ( pb ) , 0 ) ;
 CFA = avio_rl32 ( pb ) ;
 set_metadata_int ( & st -> metadata , "brightness" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "contrast" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "gamma" , avio_rl32 ( pb ) , 1 ) ;
 avio_skip ( pb , 12 + 16 ) ;
 set_metadata_float ( & st -> metadata , "wbgain[0].r" , av_int2float ( avio_rl32 ( pb ) ) , 1 ) ;
 set_metadata_float ( & st -> metadata , "wbgain[0].b" , av_int2float ( avio_rl32 ( pb ) ) , 1 ) ;
 avio_skip ( pb , 36 ) ;
 st -> codecpar -> bits_per_coded_sample = avio_rl32 ( pb ) ;
 if ( compression == CC_RGB ) {
 if ( biBitCount == 8 ) {
 st -> codecpar -> format = AV_PIX_FMT_GRAY8 ;
 }
 else if ( biBitCount == 16 ) {
 st -> codecpar -> format = AV_PIX_FMT_GRAY16LE ;
 }
 else if ( biBitCount == 24 ) {
 st -> codecpar -> format = AV_PIX_FMT_BGR24 ;
 }
 else if ( biBitCount == 48 ) {
 st -> codecpar -> format = AV_PIX_FMT_BGR48LE ;
 }
 else {
 avpriv_request_sample ( avctx , "unsupported biBitCount %i" , biBitCount ) ;
 return AVERROR_INVALIDDATA ;
 }
 }
 else if ( compression == CC_UNINT ) {
 switch ( CFA & 0xFFFFFF ) {
 case CFA_BAYER : if ( biBitCount == 8 ) {
 st -> codecpar -> format = AV_PIX_FMT_BAYER_GBRG8 ;
 }
 else if ( biBitCount == 16 ) {
 st -> codecpar -> format = AV_PIX_FMT_BAYER_GBRG16LE ;
 }
 else {
 avpriv_request_sample ( avctx , "unsupported biBitCount %i" , biBitCount ) ;
 return AVERROR_INVALIDDATA ;
 }
 break ;
 case CFA_BAYERFLIP : if ( biBitCount == 8 ) {
 st -> codecpar -> format = AV_PIX_FMT_BAYER_RGGB8 ;
 }
 else if ( biBitCount == 16 ) {
 st -> codecpar -> format = AV_PIX_FMT_BAYER_RGGB16LE ;
 }
 else {
 avpriv_request_sample ( avctx , "unsupported biBitCount %i" , biBitCount ) ;
 return AVERROR_INVALIDDATA ;
 }
 break ;
 default : avpriv_request_sample ( avctx , "unsupported Color Field Array (CFA) %i" , CFA & 0xFFFFFF ) ;
 return AVERROR_INVALIDDATA ;
 }
 }
 else {
 avpriv_request_sample ( avctx , "unsupported compression %i" , compression ) ;
 return AVERROR_INVALIDDATA ;
 }
 avio_skip ( pb , 668 ) ;
 set_metadata_int ( & st -> metadata , "shutter_ns" , avio_rl32 ( pb ) , 0 ) ;
 avio_skip ( pb , 24 ) ;
 # define DESCRIPTION_SIZE 4096 description = av_malloc ( DESCRIPTION_SIZE + 1 ) ;
 if ( ! description ) return AVERROR ( ENOMEM ) ;
 i = avio_get_str ( pb , DESCRIPTION_SIZE , description , DESCRIPTION_SIZE + 1 ) ;
 if ( i < DESCRIPTION_SIZE ) avio_skip ( pb , DESCRIPTION_SIZE - i ) ;
 if ( description [ 0 ] ) av_dict_set ( & st -> metadata , "description" , description , AV_DICT_DONT_STRDUP_VAL ) ;
 else av_free ( description ) ;
 avio_skip ( pb , 1176 ) ;
 set_metadata_int ( & st -> metadata , "enable_crop" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "crop_left" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "crop_top" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "crop_right" , avio_rl32 ( pb ) , 1 ) ;
 set_metadata_int ( & st -> metadata , "crop_bottom" , avio_rl32 ( pb ) , 1 ) ;
 avio_seek ( pb , offImageOffsets , SEEK_SET ) ;
 for ( i = 0 ;
 i < st -> duration ;
 i ++ ) {
 if ( avio_feof ( pb ) ) return AVERROR_INVALIDDATA ;
 av_add_index_entry ( st , avio_rl64 ( pb ) , i , 0 , 0 , AVINDEX_KEYFRAME ) ;
 }
 return 0 ;
 }


lldp_decode(struct lldpd *cfg, char *frame, int s,
    struct lldpd_hardware *hardware,
    struct lldpd_chassis **newchassis, struct lldpd_port **newport)
{
	struct lldpd_chassis *chassis;
	struct lldpd_port *port;
	char lldpaddr[ETHER_ADDR_LEN];
	const char dot1[] = LLDP_TLV_ORG_DOT1;
	const char dot3[] = LLDP_TLV_ORG_DOT3;
	const char med[] = LLDP_TLV_ORG_MED;
	const char dcbx[] = LLDP_TLV_ORG_DCBX;
	unsigned char orgid[3];
	int length, gotend = 0, ttl_received = 0;
	int tlv_size, tlv_type, tlv_subtype, tlv_count = 0;
	u_int8_t *pos, *tlv;
	char *b;
#ifdef ENABLE_DOT1
	struct lldpd_vlan *vlan = NULL;
	int vlan_len;
	struct lldpd_ppvid *ppvid;
	struct lldpd_pi *pi = NULL;
#endif
	struct lldpd_mgmt *mgmt;
	int af;
	u_int8_t addr_str_length, addr_str_buffer[32];
	u_int8_t addr_family, addr_length, *addr_ptr, iface_subtype;
	u_int32_t iface_number, iface;
#ifdef ENABLE_CUSTOM
	struct lldpd_custom *custom = NULL;
#endif

	log_debug("lldp", "receive LLDP PDU on %s",
	    hardware->h_ifname);

	if ((chassis = calloc(1, sizeof(struct lldpd_chassis))) == NULL) {
		log_warn("lldp", "failed to allocate remote chassis");
		return -1;
	}
	TAILQ_INIT(&chassis->c_mgmt);
	if ((port = calloc(1, sizeof(struct lldpd_port))) == NULL) {
		log_warn("lldp", "failed to allocate remote port");
		free(chassis);
		return -1;
	}
#ifdef ENABLE_DOT1
	TAILQ_INIT(&port->p_vlans);
	TAILQ_INIT(&port->p_ppvids);
	TAILQ_INIT(&port->p_pids);
#endif
#ifdef ENABLE_CUSTOM
	TAILQ_INIT(&port->p_custom_list);
#endif

	length = s;
	pos = (u_int8_t*)frame;

	if (length < 2*ETHER_ADDR_LEN + sizeof(u_int16_t)) {
		log_warnx("lldp", "too short frame received on %s", hardware->h_ifname);
		goto malformed;
	}
	PEEK_BYTES(lldpaddr, ETHER_ADDR_LEN);
	if (memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_BRIDGE, ETHER_ADDR_LEN) &&
	    memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_NONTPMR_BRIDGE, ETHER_ADDR_LEN) &&
	    memcmp(lldpaddr, (const char [])LLDP_ADDR_NEAREST_CUSTOMER_BRIDGE, ETHER_ADDR_LEN)) {
		log_info("lldp", "frame not targeted at LLDP multicast address received on %s",
		    hardware->h_ifname);
		goto malformed;
	}
	PEEK_DISCARD(ETHER_ADDR_LEN);	/* Skip source address */
	if (PEEK_UINT16 != ETHERTYPE_LLDP) {
		log_info("lldp", "non LLDP frame received on %s",
		    hardware->h_ifname);
		goto malformed;
	}

	while (length && (!gotend)) {
		if (length < 2) {
			log_warnx("lldp", "tlv header too short received on %s",
			    hardware->h_ifname);
			goto malformed;
		}
		tlv_size = PEEK_UINT16;
		tlv_type = tlv_size >> 9;
		tlv_size = tlv_size & 0x1ff;
		(void)PEEK_SAVE(tlv);
		if (length < tlv_size) {
			log_warnx("lldp", "frame too short for tlv received on %s",
			    hardware->h_ifname);
			goto malformed;
		}
		/* Check order for mandatory TLVs */
		tlv_count++;
		switch (tlv_type) {
		case LLDP_TLV_CHASSIS_ID:
			if (tlv_count != 1) {
				log_warnx("lldp", "first TLV should be a chassis ID on %s, not %d",
				    hardware->h_ifname, tlv_type);
				goto malformed;
			}
			break;
		case LLDP_TLV_PORT_ID:
			if (tlv_count != 2) {
				log_warnx("lldp", "second TLV should be a port ID on %s, not %d",
				    hardware->h_ifname, tlv_type);
				goto malformed;
			}
			break;
		case LLDP_TLV_TTL:
			if (tlv_count != 3) {
				log_warnx("lldp", "third TLV should be a TTL on %s, not %d",
				    hardware->h_ifname, tlv_type);
				goto malformed;
			}
			break;
		}

		switch (tlv_type) {
		case LLDP_TLV_END:
			if (tlv_size != 0) {
				log_warnx("lldp", "lldp end received with size not null on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			if (length)
				log_debug("lldp", "extra data after lldp end on %s",
				    hardware->h_ifname);
			gotend = 1;
			break;
		case LLDP_TLV_CHASSIS_ID:
		case LLDP_TLV_PORT_ID:
			CHECK_TLV_SIZE(2, "Port/Chassis Id");
			CHECK_TLV_MAX_SIZE(256, "Port/Chassis Id");
			tlv_subtype = PEEK_UINT8;
			if ((tlv_subtype == 0) || (tlv_subtype > 7)) {
				log_warnx("lldp", "unknown subtype for tlv id received on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			if ((b = (char *)calloc(1, tlv_size - 1)) == NULL) {
				log_warn("lldp", "unable to allocate memory for id tlv "
				    "received on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			PEEK_BYTES(b, tlv_size - 1);
			if (tlv_type == LLDP_TLV_PORT_ID) {
				if (port->p_id != NULL) {
					log_warnx("lldp", "Port ID TLV received twice on %s",
					    hardware->h_ifname);
					free(b);
					goto malformed;
				}
				port->p_id_subtype = tlv_subtype;
				port->p_id = b;
				port->p_id_len = tlv_size - 1;
			} else {
				if (chassis->c_id != NULL) {
					log_warnx("lldp", "Chassis ID TLV received twice on %s",
					    hardware->h_ifname);
					free(b);
					goto malformed;
				}
				chassis->c_id_subtype = tlv_subtype;
				chassis->c_id = b;
				chassis->c_id_len = tlv_size - 1;
			}
			break;
		case LLDP_TLV_TTL:
			if (ttl_received) {
				log_warnx("lldp", "TTL TLV received twice on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			CHECK_TLV_SIZE(2, "TTL");
			port->p_ttl = PEEK_UINT16;
			ttl_received = 1;
			break;
		case LLDP_TLV_PORT_DESCR:
		case LLDP_TLV_SYSTEM_NAME:
		case LLDP_TLV_SYSTEM_DESCR:
			if (tlv_size < 1) {
				log_debug("lldp", "empty tlv received on %s",
				    hardware->h_ifname);
				break;
			}
			if ((b = (char *)calloc(1, tlv_size + 1)) == NULL) {
				log_warn("lldp", "unable to allocate memory for string tlv "
				    "received on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			PEEK_BYTES(b, tlv_size);
			if (tlv_type == LLDP_TLV_PORT_DESCR)
				port->p_descr = b;
			else if (tlv_type == LLDP_TLV_SYSTEM_NAME)
				chassis->c_name = b;
			else chassis->c_descr = b;
			break;
		case LLDP_TLV_SYSTEM_CAP:
			CHECK_TLV_SIZE(4, "System capabilities");
			chassis->c_cap_available = PEEK_UINT16;
			chassis->c_cap_enabled = PEEK_UINT16;
			break;
		case LLDP_TLV_MGMT_ADDR:
			CHECK_TLV_SIZE(1, "Management address");
			addr_str_length = PEEK_UINT8;
			if (addr_str_length > sizeof(addr_str_buffer)) {
				log_warnx("lldp", "too large management address on %s",
				    hardware->h_ifname);
				goto malformed;
			}
			CHECK_TLV_SIZE(1 + addr_str_length, "Management address");
			PEEK_BYTES(addr_str_buffer, addr_str_length);
			addr_length = addr_str_length - 1;
			addr_family = addr_str_buffer[0];
			addr_ptr = &addr_str_buffer[1];
			CHECK_TLV_SIZE(1 + addr_str_length + 5, "Management address");
			iface_subtype = PEEK_UINT8;
			iface_number = PEEK_UINT32;

			af = lldpd_af_from_lldp_proto(addr_family);
			if (af == LLDPD_AF_UNSPEC)
				break;
			if (iface_subtype == LLDP_MGMT_IFACE_IFINDEX)
				iface = iface_number;
			else
				iface = 0;
			mgmt = lldpd_alloc_mgmt(af, addr_ptr, addr_length, iface);
			if (mgmt == NULL) {
				if (errno == ENOMEM)
					log_warn("lldp", "unable to allocate memory "
					    "for management address");
				else
					log_warn("lldp", "too large management address "
					    "received on %s", hardware->h_ifname);
				goto malformed;
			}
			TAILQ_INSERT_TAIL(&chassis->c_mgmt, mgmt, m_entries);
			break;
		case LLDP_TLV_ORG:
			CHECK_TLV_SIZE(1 + (int)sizeof(orgid), "Organisational");
			PEEK_BYTES(orgid, sizeof(orgid));
			tlv_subtype = PEEK_UINT8;
			if (memcmp(dot1, orgid, sizeof(orgid)) == 0) {
#ifndef ENABLE_DOT1
				hardware->h_rx_unrecognized_cnt++;
#else
				/* Dot1 */
				switch (tlv_subtype) {
				case LLDP_TLV_DOT1_VLANNAME:
					CHECK_TLV_SIZE(7, "VLAN");
					if ((vlan = (struct lldpd_vlan *)calloc(1,
						    sizeof(struct lldpd_vlan))) == NULL) {
						log_warn("lldp", "unable to alloc vlan "
						    "structure for "
						    "tlv received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					vlan->v_vid = PEEK_UINT16;
					vlan_len = PEEK_UINT8;
					CHECK_TLV_SIZE(7 + vlan_len, "VLAN");
					if ((vlan->v_name =
						(char *)calloc(1, vlan_len + 1)) == NULL) {
						log_warn("lldp", "unable to alloc vlan name for "
						    "tlv received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					PEEK_BYTES(vlan->v_name, vlan_len);
					TAILQ_INSERT_TAIL(&port->p_vlans,
					    vlan, v_entries);
					vlan = NULL;
					break;
				case LLDP_TLV_DOT1_PVID:
					CHECK_TLV_SIZE(6, "PVID");
					port->p_pvid = PEEK_UINT16;
					break;
				case LLDP_TLV_DOT1_PPVID:
					CHECK_TLV_SIZE(7, "PPVID");
					/* validation needed */
					/* PPVID has to be unique if more than
					   one PPVID TLVs are received  -
					   discard if duplicate */
					/* if support bit is not set and
					   enabled bit is set - PPVID TLV is
					   considered error  and discarded */
					/* if PPVID > 4096 - bad and discard */
					if ((ppvid = (struct lldpd_ppvid *)calloc(1,
						    sizeof(struct lldpd_ppvid))) == NULL) {
						log_warn("lldp", "unable to alloc ppvid "
						    "structure for "
						    "tlv received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					ppvid->p_cap_status = PEEK_UINT8;
					ppvid->p_ppvid = PEEK_UINT16;
					TAILQ_INSERT_TAIL(&port->p_ppvids,
					    ppvid, p_entries);
					break;
				case LLDP_TLV_DOT1_PI:
					/* validation needed */
					/* PI has to be unique if more than
					   one PI TLVs are received  - discard
					   if duplicate ?? */
					CHECK_TLV_SIZE(5, "PI");
					if ((pi = (struct lldpd_pi *)calloc(1,
						    sizeof(struct lldpd_pi))) == NULL) {
						log_warn("lldp", "unable to alloc PI "
						    "structure for "
						    "tlv received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					pi->p_pi_len = PEEK_UINT8;
					CHECK_TLV_SIZE(5 + pi->p_pi_len, "PI");
					if ((pi->p_pi =
						(char *)calloc(1, pi->p_pi_len)) == NULL) {
						log_warn("lldp", "unable to alloc pid name for "
						    "tlv received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					PEEK_BYTES(pi->p_pi, pi->p_pi_len);
					TAILQ_INSERT_TAIL(&port->p_pids,
					    pi, p_entries);
					pi = NULL;
					break;
				default:
					/* Unknown Dot1 TLV, ignore it */
					hardware->h_rx_unrecognized_cnt++;
				}
#endif
			} else if (memcmp(dot3, orgid, sizeof(orgid)) == 0) {
#ifndef ENABLE_DOT3
				hardware->h_rx_unrecognized_cnt++;
#else
				/* Dot3 */
				switch (tlv_subtype) {
				case LLDP_TLV_DOT3_MAC:
					CHECK_TLV_SIZE(9, "MAC/PHY");
					port->p_macphy.autoneg_support = PEEK_UINT8;
					port->p_macphy.autoneg_enabled =
					    (port->p_macphy.autoneg_support & 0x2) >> 1;
					port->p_macphy.autoneg_support =
					    port->p_macphy.autoneg_support & 0x1;
					port->p_macphy.autoneg_advertised =
					    PEEK_UINT16;
					port->p_macphy.mau_type = PEEK_UINT16;
					break;
				case LLDP_TLV_DOT3_LA:
					CHECK_TLV_SIZE(9, "Link aggregation");
					PEEK_DISCARD_UINT8;
					port->p_aggregid = PEEK_UINT32;
					break;
				case LLDP_TLV_DOT3_MFS:
					CHECK_TLV_SIZE(6, "MFS");
					port->p_mfs = PEEK_UINT16;
					break;
				case LLDP_TLV_DOT3_POWER:
					CHECK_TLV_SIZE(7, "Power");
					port->p_power.devicetype = PEEK_UINT8;
					port->p_power.supported =
						(port->p_power.devicetype & 0x2) >> 1;
					port->p_power.enabled =
						(port->p_power.devicetype & 0x4) >> 2;
					port->p_power.paircontrol =
						(port->p_power.devicetype & 0x8) >> 3;
					port->p_power.devicetype =
						(port->p_power.devicetype & 0x1)?
						LLDP_DOT3_POWER_PSE:LLDP_DOT3_POWER_PD;
					port->p_power.pairs = PEEK_UINT8;
					port->p_power.class = PEEK_UINT8;
					/* 802.3at? */
					if (tlv_size >= 12) {
						port->p_power.powertype = PEEK_UINT8;
						port->p_power.source =
						    (port->p_power.powertype & (1<<5 | 1<<4)) >> 4;
						port->p_power.priority =
						    (port->p_power.powertype & (1<<1 | 1<<0));
						port->p_power.powertype =
						    (port->p_power.powertype & (1<<7))?
						    LLDP_DOT3_POWER_8023AT_TYPE1:
						    LLDP_DOT3_POWER_8023AT_TYPE2;
						port->p_power.requested = PEEK_UINT16;
						port->p_power.allocated = PEEK_UINT16;
					} else
						port->p_power.powertype =
						    LLDP_DOT3_POWER_8023AT_OFF;
					/* 802.3bt? */
					if (tlv_size >= 29) {
						port->p_power.requested_a = PEEK_UINT16;
						port->p_power.requested_b = PEEK_UINT16;
						port->p_power.allocated_a = PEEK_UINT16;
						port->p_power.allocated_b = PEEK_UINT16;
						port->p_power.pse_status = PEEK_UINT16;
						port->p_power.pd_status =
						    (port->p_power.pse_status & (1<<13 | 1<<12)) >> 12;
						port->p_power.pse_pairs_ext =
						    (port->p_power.pse_status & (1<<11 | 1<<10)) >> 10;
						port->p_power.class_a =
						    (port->p_power.pse_status & (1<<9 | 1<<8 | 1<<7)) >> 7;
						port->p_power.class_b =
						    (port->p_power.pse_status & (1<<6 | 1<<5 | 1<<4)) >> 4;
						port->p_power.class_ext =
						    (port->p_power.pse_status & 0xf);
						port->p_power.pse_status =
						    (port->p_power.pse_status & (1<<15 | 1<<14)) >> 14;
						port->p_power.type_ext = PEEK_UINT8;
						port->p_power.pd_load =
						    (port->p_power.type_ext & 0x1);
						port->p_power.type_ext =
						    ((port->p_power.type_ext & (1<<3 | 1<<2 | 1<<1)) + 1);
						port->p_power.pse_max = PEEK_UINT16;
					} else {
						port->p_power.type_ext =
						    LLDP_DOT3_POWER_8023BT_OFF;
					}
					break;
				default:
					/* Unknown Dot3 TLV, ignore it */
					hardware->h_rx_unrecognized_cnt++;
				}
#endif
			} else if (memcmp(med, orgid, sizeof(orgid)) == 0) {
				/* LLDP-MED */
#ifndef ENABLE_LLDPMED
				hardware->h_rx_unrecognized_cnt++;
#else
				u_int32_t policy;
				unsigned loctype;
				unsigned power;

				switch (tlv_subtype) {
				case LLDP_TLV_MED_CAP:
					CHECK_TLV_SIZE(7, "LLDP-MED capabilities");
					chassis->c_med_cap_available = PEEK_UINT16;
					chassis->c_med_type = PEEK_UINT8;
					port->p_med_cap_enabled |=
					    LLDP_MED_CAP_CAP;
					break;
				case LLDP_TLV_MED_POLICY:
					CHECK_TLV_SIZE(8, "LLDP-MED policy");
					policy = PEEK_UINT32;
					if (((policy >> 24) < 1) ||
					    ((policy >> 24) > LLDP_MED_APPTYPE_LAST)) {
						log_info("lldp", "unknown policy field %d "
						    "received on %s",
						    policy,
						    hardware->h_ifname);
						break;
					}
					port->p_med_policy[(policy >> 24) - 1].type =
					    (policy >> 24);
					port->p_med_policy[(policy >> 24) - 1].unknown =
					    ((policy & 0x800000) != 0);
					port->p_med_policy[(policy >> 24) - 1].tagged =
					    ((policy & 0x400000) != 0);
					port->p_med_policy[(policy >> 24) - 1].vid =
					    (policy & 0x001FFE00) >> 9;
					port->p_med_policy[(policy >> 24) - 1].priority =
					    (policy & 0x1C0) >> 6;
					port->p_med_policy[(policy >> 24) - 1].dscp =
					    policy & 0x3F;
					port->p_med_cap_enabled |=
					    LLDP_MED_CAP_POLICY;
					break;
				case LLDP_TLV_MED_LOCATION:
					CHECK_TLV_SIZE(5, "LLDP-MED Location");
					loctype = PEEK_UINT8;
					if ((loctype < 1) ||
					    (loctype > LLDP_MED_LOCFORMAT_LAST)) {
						log_info("lldp", "unknown location type "
						    "received on %s",
						    hardware->h_ifname);
						break;
					}
					if ((port->p_med_location[loctype - 1].data =
						(char*)malloc(tlv_size - 5)) == NULL) {
						log_warn("lldp", "unable to allocate memory "
						    "for LLDP-MED location for "
						    "frame received on %s",
						    hardware->h_ifname);
						goto malformed;
					}
					PEEK_BYTES(port->p_med_location[loctype - 1].data,
					    tlv_size - 5);
					port->p_med_location[loctype - 1].data_len =
					    tlv_size - 5;
					port->p_med_location[loctype - 1].format = loctype;
					port->p_med_cap_enabled |=
					    LLDP_MED_CAP_LOCATION;
					break;
				case LLDP_TLV_MED_MDI:
					CHECK_TLV_SIZE(7, "LLDP-MED PoE-MDI");
					power = PEEK_UINT8;
					switch (power & 0xC0) {
					case 0x0:
						port->p_med_power.devicetype = LLDP_MED_POW_TYPE_PSE;
						port->p_med_cap_enabled |=
						    LLDP_MED_CAP_MDI_PSE;
						switch (power & 0x30) {
						case 0x0:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_UNKNOWN;
							break;
						case 0x10:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_PRIMARY;
							break;
						case 0x20:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_BACKUP;
							break;
						default:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_RESERVED;
						}
						break;
					case 0x40:
						port->p_med_power.devicetype = LLDP_MED_POW_TYPE_PD;
						port->p_med_cap_enabled |=
						    LLDP_MED_CAP_MDI_PD;
						switch (power & 0x30) {
						case 0x0:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_UNKNOWN;
							break;
						case 0x10:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_PSE;
							break;
						case 0x20:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_LOCAL;
							break;
						default:
							port->p_med_power.source =
							    LLDP_MED_POW_SOURCE_BOTH;
						}
						break;
					default:
						port->p_med_power.devicetype =
						    LLDP_MED_POW_TYPE_RESERVED;
					}
					if ((power & 0x0F) > LLDP_MED_POW_PRIO_LOW)
						port->p_med_power.priority =
						    LLDP_MED_POW_PRIO_UNKNOWN;
					else
						port->p_med_power.priority =
						    power & 0x0F;
					port->p_med_power.val = PEEK_UINT16;
					break;
				case LLDP_TLV_MED_IV_HW:
				case LLDP_TLV_MED_IV_SW:
				case LLDP_TLV_MED_IV_FW:
				case LLDP_TLV_MED_IV_SN:
				case LLDP_TLV_MED_IV_MANUF:
				case LLDP_TLV_MED_IV_MODEL:
				case LLDP_TLV_MED_IV_ASSET:
					if (tlv_size <= 4)
						b = NULL;
					else {
						if ((b = (char*)malloc(tlv_size - 3)) ==
						    NULL) {
							log_warn("lldp", "unable to allocate "
							    "memory for LLDP-MED "
							    "inventory for frame "
							    "received on %s",
							    hardware->h_ifname);
							goto malformed;
						}
						PEEK_BYTES(b, tlv_size - 4);
						b[tlv_size - 4] = '\0';
					}
					switch (tlv_subtype) {
					case LLDP_TLV_MED_IV_HW:
						chassis->c_med_hw = b;
						break;
					case LLDP_TLV_MED_IV_FW:
						chassis->c_med_fw = b;
						break;
					case LLDP_TLV_MED_IV_SW:
						chassis->c_med_sw = b;
						break;
					case LLDP_TLV_MED_IV_SN:
						chassis->c_med_sn = b;
						break;
					case LLDP_TLV_MED_IV_MANUF:
						chassis->c_med_manuf = b;
						break;
					case LLDP_TLV_MED_IV_MODEL:
						chassis->c_med_model = b;
						break;
					case LLDP_TLV_MED_IV_ASSET:
						chassis->c_med_asset = b;
						break;
					}
					port->p_med_cap_enabled |=
					    LLDP_MED_CAP_IV;
					break;
				default:
					/* Unknown LLDP MED, ignore it */
					hardware->h_rx_unrecognized_cnt++;
				}
#endif /* ENABLE_LLDPMED */
			} else if (memcmp(dcbx, orgid, sizeof(orgid)) == 0) {
				log_debug("lldp", "unsupported DCBX tlv received on %s - ignore",
				    hardware->h_ifname);
				hardware->h_rx_unrecognized_cnt++;
			} else {
				log_debug("lldp", "unknown org tlv [%02x:%02x:%02x] received on %s",
				    orgid[0], orgid[1], orgid[2],
				    hardware->h_ifname);
				hardware->h_rx_unrecognized_cnt++;
#ifdef ENABLE_CUSTOM
				custom = (struct lldpd_custom*)calloc(1, sizeof(struct lldpd_custom));
				if (!custom) {
					log_warn("lldp",
					    "unable to allocate memory for custom TLV");
					goto malformed;
				}
				custom->oui_info_len = tlv_size > 4 ? tlv_size - 4 : 0;
				memcpy(custom->oui, orgid, sizeof(custom->oui));
				custom->subtype = tlv_subtype;
				if (custom->oui_info_len > 0) {
					custom->oui_info = malloc(custom->oui_info_len);
					if (!custom->oui_info) {
						log_warn("lldp",
						    "unable to allocate memory for custom TLV data");
						goto malformed;
					}
					PEEK_BYTES(custom->oui_info, custom->oui_info_len);
				}
				TAILQ_INSERT_TAIL(&port->p_custom_list, custom, next);
				custom = NULL;
#endif
			}
			break;
		default:
			log_warnx("lldp", "unknown tlv (%d) received on %s",
			    tlv_type, hardware->h_ifname);
			hardware->h_rx_unrecognized_cnt++;
			break;
		}
		if (pos > tlv + tlv_size) {
			log_warnx("lldp", "BUG: already past TLV!");
			goto malformed;
		}
		PEEK_DISCARD(tlv + tlv_size - pos);
	}

	/* Some random check */
	if ((chassis->c_id == NULL) ||
	    (port->p_id == NULL) ||
	    (!ttl_received) ||
	    (gotend == 0)) {
		log_warnx("lldp", "some mandatory tlv are missing for frame received on %s",
		    hardware->h_ifname);
		goto malformed;
	}
	*newchassis = chassis;
	*newport = port;
	return 1;
malformed:
#ifdef ENABLE_CUSTOM
	free(custom);
#endif
#ifdef ENABLE_DOT1
	free(vlan);
	free(pi);
#endif
	lldpd_chassis_cleanup(chassis, 1);
	lldpd_port_cleanup(port, 1);
	free(port);
	return -1;
}


lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s,
            struct lldpd_hardware *hardware, struct lldpd_chassis **newchassis,
            struct lldpd_port **newport)
{
    struct lldpd_chassis *chassis;
    struct lldpd_port *port;
    const struct eth_addr lldpaddr = LLDP_MULTICAST_ADDR;
    const char dot1[] = LLDP_TLV_ORG_DOT1;
    const char dot3[] = LLDP_TLV_ORG_DOT3;
    const char med[] = LLDP_TLV_ORG_MED;
    const char avaya_oid[] = LLDP_TLV_ORG_AVAYA;
    const char dcbx[] = LLDP_TLV_ORG_DCBX;
    char orgid[3];
    int length, af;
    bool gotend = false;
    bool ttl_received = false;
    int tlv_size, tlv_type, tlv_subtype, tlv_count = 0;
    u_int8_t *pos, *tlv;
    void *b;
    struct lldpd_aa_isid_vlan_maps_tlv *isid_vlan_map = NULL;
    u_int8_t msg_auth_digest[LLDP_TLV_AA_ISID_VLAN_DIGEST_LENGTH];
    struct lldpd_mgmt *mgmt;
    u_int8_t addr_str_length, addr_str_buffer[32];
    u_int8_t addr_family, addr_length, *addr_ptr, iface_subtype;
    u_int32_t iface_number, iface;

    VLOG_DBG("receive LLDP PDU on %s", hardware->h_ifname);

    chassis = xzalloc(sizeof *chassis);
    ovs_list_init(&chassis->c_mgmt);

    port = xzalloc(sizeof *port);
    ovs_list_init(&port->p_isid_vlan_maps);

    length = s;
    pos = (u_int8_t*) frame;

    if (length < 2 * ETH_ADDR_LEN + sizeof(u_int16_t)) {
        VLOG_WARN("too short frame received on %s", hardware->h_ifname);
        goto malformed;
    }
    if (PEEK_CMP(&lldpaddr, ETH_ADDR_LEN) != 0) {
        VLOG_INFO("frame not targeted at LLDP multicast address "
                  "received on %s", hardware->h_ifname);
        goto malformed;
    }

    PEEK_DISCARD(ETH_ADDR_LEN); /* Skip source address */
    if (PEEK_UINT16 != ETHERTYPE_LLDP) {
        VLOG_INFO("non LLDP frame received on %s", hardware->h_ifname);
        goto malformed;
    }

    while (length && !gotend) {
        if (length < 2) {
            VLOG_WARN("tlv header too short received on %s",
                      hardware->h_ifname);
            goto malformed;
        }
        tlv_size = PEEK_UINT16;
        tlv_type = tlv_size >> 9;
        tlv_size = tlv_size & 0x1ff;
        (void) PEEK_SAVE(tlv);
        if (length < tlv_size) {
            VLOG_WARN("frame too short for tlv received on %s",
                      hardware->h_ifname);
            goto malformed;
        }
        /* Check order for mandatory TLVs */
        tlv_count++;
        switch (tlv_type) {
        case LLDP_TLV_CHASSIS_ID:
            if (tlv_count != 1) {
                VLOG_WARN("first TLV should be a chassis ID on %s, not %d",
                          hardware->h_ifname, tlv_type);
                goto malformed;
            }
            break;
        case LLDP_TLV_PORT_ID:
            if (tlv_count != 2) {
                VLOG_WARN("second TLV should be a port ID on %s, not %d",
                          hardware->h_ifname, tlv_type);
                goto malformed;
            }
            break;
        case LLDP_TLV_TTL:
            if (tlv_count != 3) {
                VLOG_WARN("third TLV should be a TTL on %s, not %d",
                          hardware->h_ifname, tlv_type);
                goto malformed;
            }
            break;
        }

        switch (tlv_type) {
        case LLDP_TLV_END:
            if (tlv_size != 0) {
                VLOG_WARN("lldp end received with size not null on %s",
                          hardware->h_ifname);
                goto malformed;
            }
            if (length) {
                VLOG_DBG("extra data after lldp end on %s",
                         hardware->h_ifname);
            }
            gotend = true;
            break;

        case LLDP_TLV_CHASSIS_ID:
        case LLDP_TLV_PORT_ID:
            CHECK_TLV_SIZE(2, "Port/Chassis Id");
            CHECK_TLV_MAX_SIZE(256, "Port/Chassis Id");
            tlv_subtype = PEEK_UINT8;
            if (tlv_subtype == 0 || tlv_subtype > 7) {
                VLOG_WARN("unknown subtype for tlv id received on %s",
                          hardware->h_ifname);
                goto malformed;
            }
            b = xzalloc(tlv_size - 1);
            PEEK_BYTES(b, tlv_size - 1);
            if (tlv_type == LLDP_TLV_PORT_ID) {
                if (port->p_id != NULL) {
                    VLOG_WARN("Port ID TLV received twice on %s",
                              hardware->h_ifname);
                    free(b);
                    goto malformed;
                }
                port->p_id_subtype = tlv_subtype;
                port->p_id = b;
                port->p_id_len = tlv_size - 1;
            } else {
                if (chassis->c_id != NULL) {
                    VLOG_WARN("Chassis ID TLV received twice on %s",
                              hardware->h_ifname);
                    free(b);
                    goto malformed;
                }
                chassis->c_id_subtype = tlv_subtype;
                chassis->c_id = b;
                chassis->c_id_len = tlv_size - 1;
            }
            break;

        case LLDP_TLV_TTL:
            if (ttl_received) {
                VLOG_WARN("TTL TLV received twice on %s",
                          hardware->h_ifname);
                goto malformed;
            }
            CHECK_TLV_SIZE(2, "TTL");
            chassis->c_ttl = PEEK_UINT16;
            ttl_received = true;
            break;

        case LLDP_TLV_PORT_DESCR:
        case LLDP_TLV_SYSTEM_NAME:
        case LLDP_TLV_SYSTEM_DESCR:
            if (tlv_size < 1) {
                VLOG_DBG("empty tlv received on %s", hardware->h_ifname);
                break;
            }
            b = xzalloc(tlv_size + 1);
            PEEK_BYTES(b, tlv_size);
            if (tlv_type == LLDP_TLV_PORT_DESCR) {
                port->p_descr = b;
            } else if (tlv_type == LLDP_TLV_SYSTEM_NAME) {
                chassis->c_name = b;
            } else {
                chassis->c_descr = b;
            }
            break;

        case LLDP_TLV_SYSTEM_CAP:
            CHECK_TLV_SIZE(4, "System capabilities");
            chassis->c_cap_available = PEEK_UINT16;
            chassis->c_cap_enabled = PEEK_UINT16;
            break;

        case LLDP_TLV_MGMT_ADDR:
            CHECK_TLV_SIZE(1, "Management address");
            addr_str_length = PEEK_UINT8;
            if (addr_str_length > sizeof(addr_str_buffer)) {
                VLOG_WARN("too large management address on %s",
                          hardware->h_ifname);
                goto malformed;
            }
            CHECK_TLV_SIZE(1 + addr_str_length, "Management address");
            PEEK_BYTES(addr_str_buffer, addr_str_length);
            addr_length = addr_str_length - 1;
            addr_family = addr_str_buffer[0];
            addr_ptr = &addr_str_buffer[1];
            CHECK_TLV_SIZE(1 + addr_str_length + 5, "Management address");
            iface_subtype = PEEK_UINT8;
            iface_number = PEEK_UINT32;

            af = lldpd_af_from_lldp_proto(addr_family);
            if (af == LLDPD_AF_UNSPEC) {
                break;
            }
            iface = iface_subtype == LLDP_MGMT_IFACE_IFINDEX ?
                iface_number : 0;
            mgmt = lldpd_alloc_mgmt(af, addr_ptr, addr_length, iface);
            if (mgmt == NULL) {
                VLOG_WARN("unable to allocate memory for management address");
                goto malformed;
            }
            ovs_list_push_back(&chassis->c_mgmt, &mgmt->m_entries);
            break;

        case LLDP_TLV_ORG:
            CHECK_TLV_SIZE(1 + sizeof orgid, "Organisational");
            PEEK_BYTES(orgid, sizeof orgid);
            tlv_subtype = PEEK_UINT8;
            if (memcmp(dot1, orgid, sizeof orgid) == 0) {
                hardware->h_rx_unrecognized_cnt++;
            } else if (memcmp(dot3, orgid, sizeof orgid) == 0) {
                hardware->h_rx_unrecognized_cnt++;
            } else if (memcmp(med, orgid, sizeof orgid) == 0) {
                /* LLDP-MED */
                hardware->h_rx_unrecognized_cnt++;
            } else if (memcmp(avaya_oid, orgid, sizeof orgid) == 0) {
                u_int32_t aa_element_dword;
                u_int16_t aa_system_id_word;
                u_int16_t aa_status_vlan_word;
                u_int8_t aa_element_state;
                unsigned short num_mappings;

                switch(tlv_subtype) {
                case LLDP_TLV_AA_ELEMENT_SUBTYPE:
                    PEEK_BYTES(&msg_auth_digest, sizeof msg_auth_digest);

                    aa_element_dword = PEEK_UINT32;

                    /* Type is first 6 most-significant bits of
                     * aa_element_dword */
                    port->p_element.type = aa_element_dword >> 26;

                    /* State is 6 most significant bits of aa_element_dword */
                    aa_element_state = (aa_element_dword >> 20) & 0x3F;

                    /* vlan tagging requirement is the bit 1(left to right)
                     * of the 6 bits state (1 based) */
                    port->p_element.vlan_tagging =
                        (aa_element_state >> 5) & 0x1;

                    /* Automatic provision mode is the bit 2/3(left to right)
                     * of the 6 bits state (1 based) */
                    port->p_element.auto_prov_mode =
                        (aa_element_state >> 3) & 0x3;

                    /* mgmt_vlan is the 12 bits of aa_element_dword from
                     * bit 12 */
                    port->p_element.mgmt_vlan =
                        (aa_element_dword >> 8) & 0xFFF;
                    VLOG_INFO("Element type: %X, vlan tagging %X, "
                              "auto prov mode %x, Mgmt vlan: %X",
                              port->p_element.type,
                              port->p_element.vlan_tagging,
                              port->p_element.auto_prov_mode,
                              port->p_element.mgmt_vlan);

                    PEEK_BYTES(&port->p_element.system_id.system_mac,
                               sizeof port->p_element.system_id.system_mac);
                    VLOG_INFO("System mac: "ETH_ADDR_FMT,
                        ETH_ADDR_ARGS(port->p_element.system_id.system_mac));
                    aa_system_id_word = PEEK_UINT16;
                    port->p_element.system_id.conn_type =
                        aa_system_id_word >> 13;
                    port->p_element.system_id.rsvd = aa_system_id_word &
                        0x03FF;
                    PEEK_BYTES(&port->p_element.system_id.rsvd2,
                               sizeof port->p_element.system_id.rsvd2);
                    break;

                case LLDP_TLV_AA_ISID_VLAN_ASGNS_SUBTYPE:
                    PEEK_BYTES(&msg_auth_digest, sizeof msg_auth_digest);

                    /* Subtract off tlv type and length (2Bytes) + OUI (3B) +
                     * Subtype (1B) + MSG DIGEST (32B).
                     */
                    num_mappings = tlv_size - 4 -
                        LLDP_TLV_AA_ISID_VLAN_DIGEST_LENGTH;
                    if (num_mappings % 5 != 0) {
                        VLOG_INFO("malformed vlan-isid mappings tlv received");
                        goto malformed;
                    }

                    num_mappings /= 5; /* Each mapping is 5 Bytes */
                    for(; num_mappings > 0; num_mappings--) {
                        uint8_t isid[3];

                        isid_vlan_map = xzalloc(sizeof *isid_vlan_map);
                        aa_status_vlan_word = PEEK_UINT16;

                        /* Status is first 4 most-significant bits. */
                        isid_vlan_map->isid_vlan_data.status =
                            aa_status_vlan_word >> 12;

                        /* Vlan is last 12 bits */
                        isid_vlan_map->isid_vlan_data.vlan =
                            aa_status_vlan_word & 0x0FFF;
                        PEEK_BYTES(isid, 3);
                        isid_vlan_map->isid_vlan_data.isid =
                            (isid[0] << 16) | (isid[1] << 8) | isid[2];
                        ovs_list_push_back(&port->p_isid_vlan_maps,
                                       &isid_vlan_map->m_entries);
                        isid_vlan_map = NULL;
                    }
                    break;

                default:
                    hardware->h_rx_unrecognized_cnt++;
                    VLOG_INFO("Unrecogised tlv subtype received");
                    break;
                }
            } else if (memcmp(dcbx, orgid, sizeof orgid) == 0) {
                VLOG_DBG("unsupported DCBX tlv received on %s "
                         "- ignore", hardware->h_ifname);
                hardware->h_rx_unrecognized_cnt++;
            } else {
                VLOG_INFO("unknown org tlv [%02x:%02x:%02x] received "
                          "on %s", orgid[0], orgid[1], orgid[2],
                          hardware->h_ifname);
                hardware->h_rx_unrecognized_cnt++;
            }
            break;
        default:
            VLOG_WARN("unknown tlv (%d) received on %s",
                      tlv_type,
                      hardware->h_ifname);
            hardware->h_rx_unrecognized_cnt++;
            goto malformed;
        }
        if (pos > tlv + tlv_size) {
            VLOG_WARN("BUG: already past TLV!");
            goto malformed;
        }
        PEEK_DISCARD(tlv + tlv_size - pos);
    }

    /* Some random check */
    if (!chassis->c_id || !port->p_id || !ttl_received || !gotend) {
        VLOG_WARN("some mandatory tlv are missing for frame received "
                  "on %s", hardware->h_ifname);
        goto malformed;
    }
    *newchassis = chassis;
    *newport = port;
    return 1;

malformed:
    lldpd_chassis_cleanup(chassis, true);
    lldpd_port_cleanup(port, true);
    free(port);
    return -1;
}


client_send_params(gnutls_session_t session,
		   gnutls_buffer_t extdata,
		   const gnutls_psk_client_credentials_t cred)
{
	int ret, ext_offset = 0;
	uint8_t binder_value[MAX_HASH_SIZE];
	size_t spos;
	gnutls_datum_t username = {NULL, 0};
	gnutls_datum_t user_key = {NULL, 0}, rkey = {NULL, 0};
	gnutls_datum_t client_hello;
	unsigned next_idx;
	const mac_entry_st *prf_res = NULL;
	const mac_entry_st *prf_psk = NULL;
	struct timespec cur_time;
	uint32_t ticket_age, ob_ticket_age;
	int free_username = 0;
	psk_auth_info_t info = NULL;
	unsigned psk_id_len = 0;
	unsigned binders_len, binders_pos;
	tls13_ticket_st *ticket = &session->internals.tls13_ticket;

	if (((session->internals.flags & GNUTLS_NO_TICKETS) ||
	    session->internals.tls13_ticket.ticket.data == NULL) &&
	    (!cred || !_gnutls_have_psk_credentials(cred, session))) {

		return 0;
	}

	binders_len = 0;

	/* placeholder to be filled later */
	spos = extdata->length;
	ret = _gnutls_buffer_append_prefix(extdata, 16, 0);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* First, let's see if we have a session ticket to send */
	if (!(session->internals.flags & GNUTLS_NO_TICKETS) &&
	    ticket->ticket.data != NULL) {

		/* We found a session ticket */
		if (unlikely(ticket->prf == NULL)) {
			tls13_ticket_deinit(ticket);
			ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
			goto cleanup;
		}

		prf_res = ticket->prf;

		gnutls_gettime(&cur_time);
		if (unlikely(_gnutls_timespec_cmp(&cur_time,
						  &ticket->arrival_time) < 0)) {
			gnutls_assert();
			tls13_ticket_deinit(ticket);
			goto ignore_ticket;
		}

		/* Check whether the ticket is stale */
		ticket_age = timespec_sub_ms(&cur_time, &ticket->arrival_time);
		if (ticket_age / 1000 > ticket->lifetime) {
			tls13_ticket_deinit(ticket);
			goto ignore_ticket;
		}

		ret = compute_psk_from_ticket(ticket, &rkey);
		if (ret < 0) {
			tls13_ticket_deinit(ticket);
			goto ignore_ticket;
		}

		/* Calculate obfuscated ticket age, in milliseconds, mod 2^32 */
		ob_ticket_age = ticket_age + ticket->age_add;

		if ((ret = _gnutls_buffer_append_data_prefix(extdata, 16,
							     ticket->ticket.data,
							     ticket->ticket.size)) < 0) {
			gnutls_assert();
			goto cleanup;
		}

		/* Now append the obfuscated ticket age */
		if ((ret = _gnutls_buffer_append_prefix(extdata, 32, ob_ticket_age)) < 0) {
			gnutls_assert();
			goto cleanup;
		}

		psk_id_len += 6 + ticket->ticket.size;
		binders_len += 1 + _gnutls_mac_get_algo_len(prf_res);
	}

 ignore_ticket:
	if (cred && _gnutls_have_psk_credentials(cred, session)) {
		gnutls_datum_t tkey;

		if (cred->binder_algo == NULL) {
			gnutls_assert();
			ret = gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
			goto cleanup;
		}

		prf_psk = cred->binder_algo;

		ret = _gnutls_find_psk_key(session, cred, &username, &tkey, &free_username);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		if (username.size == 0 || username.size > UINT16_MAX) {
			ret = gnutls_assert_val(GNUTLS_E_INVALID_PASSWORD);
			goto cleanup;
		}

		if (!free_username) {
			/* we need to copy the key */
			ret = _gnutls_set_datum(&user_key, tkey.data, tkey.size);
			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}
		} else {
			user_key.data = tkey.data;
			user_key.size = tkey.size;
		}

		ret = _gnutls_auth_info_init(session, GNUTLS_CRD_PSK, sizeof(psk_auth_info_st), 1);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
		assert(info != NULL);

		_gnutls_copy_psk_username(info, &username);

		if ((ret = _gnutls_buffer_append_data_prefix(extdata, 16,
							     username.data,
							     username.size)) < 0) {
			gnutls_assert();
			goto cleanup;
		}

		/* Now append the obfuscated ticket age */
		if ((ret = _gnutls_buffer_append_prefix(extdata, 32, 0)) < 0) {
			gnutls_assert();
			goto cleanup;
		}

		psk_id_len += 6 + username.size;
		binders_len += 1 + _gnutls_mac_get_algo_len(prf_psk);
	}

	/* if no tickets or identities to be sent */
	if (psk_id_len == 0) {
		/* reset extensions buffer */
		extdata->length = spos;
		return 0;
	}

	_gnutls_write_uint16(psk_id_len, &extdata->data[spos]);

	binders_pos = extdata->length-spos;
	ext_offset = _gnutls_ext_get_extensions_offset(session);

	/* Compute the binders. extdata->data points to the start
	 * of this client hello. */
	assert(extdata->length >= sizeof(mbuffer_st));
	assert(ext_offset >= (ssize_t)sizeof(mbuffer_st));
	ext_offset -= sizeof(mbuffer_st);
	client_hello.data = extdata->data+sizeof(mbuffer_st);
	client_hello.size = extdata->length-sizeof(mbuffer_st);

	next_idx = 0;

	ret = _gnutls_buffer_append_prefix(extdata, 16, binders_len);
	if (ret < 0) {
		gnutls_assert_val(ret);
		goto cleanup;
	}

	if (prf_res && rkey.size > 0) {
		ret = compute_psk_binder(session, prf_res,
					 binders_len, binders_pos,
					 ext_offset, &rkey, &client_hello, 1,
					 binder_value);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		/* Associate the selected pre-shared key with the session */
		gnutls_free(session->key.binders[next_idx].psk.data);
		session->key.binders[next_idx].psk.data = rkey.data;
		session->key.binders[next_idx].psk.size = rkey.size;
		rkey.data = NULL;

		session->key.binders[next_idx].prf = prf_res;
		session->key.binders[next_idx].resumption = 1;
		session->key.binders[next_idx].idx = next_idx;

		_gnutls_handshake_log("EXT[%p]: sent PSK resumption identity (%d)\n", session, next_idx);

		next_idx++;

		/* Add the binder */
		ret = _gnutls_buffer_append_data_prefix(extdata, 8, binder_value, prf_res->output_size);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		session->internals.hsk_flags |= HSK_TLS13_TICKET_SENT;
	}

	if (prf_psk && user_key.size > 0 && info) {
		ret = compute_psk_binder(session, prf_psk,
					 binders_len, binders_pos,
					 ext_offset, &user_key, &client_hello, 0,
					 binder_value);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		/* Associate the selected pre-shared key with the session */
		gnutls_free(session->key.binders[next_idx].psk.data);
		session->key.binders[next_idx].psk.data = user_key.data;
		session->key.binders[next_idx].psk.size = user_key.size;
		user_key.data = NULL;

		session->key.binders[next_idx].prf = prf_psk;
		session->key.binders[next_idx].resumption = 0;
		session->key.binders[next_idx].idx = next_idx;

		_gnutls_handshake_log("EXT[%p]: sent PSK identity '%s' (%d)\n", session, info->username, next_idx);

		next_idx++;

		/* Add the binder */
		ret = _gnutls_buffer_append_data_prefix(extdata, 8, binder_value, prf_psk->output_size);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret = 0;

cleanup:
	if (free_username)
		_gnutls_free_datum(&username);

	_gnutls_free_temp_key_datum(&user_key);
	_gnutls_free_temp_key_datum(&rkey);

	return ret;
}


static int blosc_c(struct thread_context* thread_context, int32_t bsize,
                   int32_t leftoverblock, int32_t ntbytes, int32_t maxbytes,
                   const uint8_t* src, const int32_t offset, uint8_t* dest,
                   uint8_t* tmp, uint8_t* tmp2) {
  blosc2_context* context = thread_context->parent_context;
  int dont_split = (context->header_flags & 0x10) >> 4;
  int dict_training = context->use_dict && context->dict_cdict == NULL;
  int32_t j, neblock, nstreams;
  int32_t cbytes;                   /* number of compressed bytes in split */
  int32_t ctbytes = 0;              /* number of compressed bytes in block */
  int64_t maxout;
  int32_t typesize = context->typesize;
  const char* compname;
  int accel;
  const uint8_t* _src;
  uint8_t *_tmp = tmp, *_tmp2 = tmp2;
  uint8_t *_tmp3 = thread_context->tmp4;
  int last_filter_index = last_filter(context->filters, 'c');
  bool memcpyed = context->header_flags & (uint8_t)BLOSC_MEMCPYED;

  if (last_filter_index >= 0 || context->prefilter != NULL) {
    /* Apply the filter pipeline just for the prefilter */
    if (memcpyed && context->prefilter != NULL) {
      // We only need the prefilter output
      _src = pipeline_c(thread_context, bsize, src, offset, dest, _tmp2, _tmp3);

      if (_src == NULL) {
        return -9;  // signals a problem with the filter pipeline
      }
      return bsize;
    }
    /* Apply regular filter pipeline */
    _src = pipeline_c(thread_context, bsize, src, offset, _tmp, _tmp2, _tmp3);

    if (_src == NULL) {
      return -9;  // signals a problem with the filter pipeline
    }
  } else {
    _src = src + offset;
  }

  assert(context->clevel > 0);

  /* Calculate acceleration for different compressors */
  accel = get_accel(context);

  /* The number of compressed data streams for this block */
  if (!dont_split && !leftoverblock && !dict_training) {
    nstreams = (int32_t)typesize;
  }
  else {
    nstreams = 1;
  }
  neblock = bsize / nstreams;
  for (j = 0; j < nstreams; j++) {
    if (!dict_training) {
      dest += sizeof(int32_t);
      ntbytes += sizeof(int32_t);
      ctbytes += sizeof(int32_t);
    }

    // See if we have a run here
    const uint8_t* ip = (uint8_t*)_src + j * neblock;
    const uint8_t* ipbound = (uint8_t*)_src + (j + 1) * neblock;
    if (get_run(ip, ipbound)) {
      // A run.  Encode the repeated byte as a negative length in the length of the split.
      int32_t value = _src[j * neblock];
      _sw32(dest - 4, -value);
      continue;
    }

    maxout = neblock;
  #if defined(HAVE_SNAPPY)
    if (context->compcode == BLOSC_SNAPPY) {
      maxout = (int32_t)snappy_max_compressed_length((size_t)neblock);
    }
  #endif /*  HAVE_SNAPPY */
    if (ntbytes + maxout > maxbytes) {
      /* avoid buffer * overrun */
      maxout = (int64_t)maxbytes - (int64_t)ntbytes;
      if (maxout <= 0) {
        return 0;                  /* non-compressible block */
      }
    }
    if (dict_training) {
      // We are in the build dict state, so don't compress
      // TODO: copy only a percentage for sampling
      memcpy(dest, _src + j * neblock, (unsigned int)neblock);
      cbytes = (int32_t)neblock;
    }
    else if (context->compcode == BLOSC_BLOSCLZ) {
      cbytes = blosclz_compress(context->clevel, _src + j * neblock,
                                (int)neblock, dest, (int)maxout);
    }
  #if defined(HAVE_LZ4)
    else if (context->compcode == BLOSC_LZ4) {
      void *hash_table = NULL;
    #ifdef HAVE_IPP
      hash_table = (void*)thread_context->lz4_hash_table;
    #endif
      cbytes = lz4_wrap_compress((char*)_src + j * neblock, (size_t)neblock,
                                 (char*)dest, (size_t)maxout, accel, hash_table);
    }
    else if (context->compcode == BLOSC_LZ4HC) {
      cbytes = lz4hc_wrap_compress((char*)_src + j * neblock, (size_t)neblock,
                                   (char*)dest, (size_t)maxout, context->clevel);
    }
  #endif /* HAVE_LZ4 */
  #if defined(HAVE_LIZARD)
    else if (context->compcode == BLOSC_LIZARD) {
      cbytes = lizard_wrap_compress((char*)_src + j * neblock, (size_t)neblock,
                                    (char*)dest, (size_t)maxout, accel);
    }
  #endif /* HAVE_LIZARD */
  #if defined(HAVE_SNAPPY)
    else if (context->compcode == BLOSC_SNAPPY) {
      cbytes = snappy_wrap_compress((char*)_src + j * neblock, (size_t)neblock,
                                    (char*)dest, (size_t)maxout);
    }
  #endif /* HAVE_SNAPPY */
  #if defined(HAVE_ZLIB)
    else if (context->compcode == BLOSC_ZLIB) {
      cbytes = zlib_wrap_compress((char*)_src + j * neblock, (size_t)neblock,
                                  (char*)dest, (size_t)maxout, context->clevel);
    }
  #endif /* HAVE_ZLIB */
  #if defined(HAVE_ZSTD)
    else if (context->compcode == BLOSC_ZSTD) {
      cbytes = zstd_wrap_compress(thread_context,
                                  (char*)_src + j * neblock, (size_t)neblock,
                                  (char*)dest, (size_t)maxout, context->clevel);
    }
  #endif /* HAVE_ZSTD */

    else {
      blosc_compcode_to_compname(context->compcode, &compname);
      fprintf(stderr, "Blosc has not been compiled with '%s' ", compname);
      fprintf(stderr, "compression support.  Please use one having it.");
      return -5;    /* signals no compression support */
    }

    if (cbytes > maxout) {
      /* Buffer overrun caused by compression (should never happen) */
      return -1;
    }
    if (cbytes < 0) {
      /* cbytes should never be negative */
      return -2;
    }
    if (!dict_training) {
      if (cbytes == 0 || cbytes == neblock) {
        /* The compressor has been unable to compress data at all. */
        /* Before doing the copy, check that we are not running into a
           buffer overflow. */
        if ((ntbytes + neblock) > maxbytes) {
          return 0;    /* Non-compressible data */
        }
        memcpy(dest, _src + j * neblock, (unsigned int)neblock);
        cbytes = neblock;
      }
      _sw32(dest - 4, cbytes);
    }
    dest += cbytes;
    ntbytes += cbytes;
    ctbytes += cbytes;
  }  /* Closes j < nstreams */

  //printf("c%d", ctbytes);
  return ctbytes;
}


static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist) { int i, tdist = 0.0f; OpusRangeCoder dump; ff_opus_rc_enc_init(&dump); ff_celt_enc_bitalloc(f, &dump); for (i = 0; i < CELT_MAX_BANDS; i++) { float bits = 0.0f; float dist = f->pvq->band_cost(f->pvq, f, &dump, i, &bits, s->lambda); tdist += dist; } *total_dist = tdist; return 0; }


static int pad_basic(bn_t m, int *p_len, int m_len, int k_len, int operation) {
	uint8_t pad = 0;
	int result = RLC_OK;
	bn_t t;

	RLC_TRY {
		bn_null(t);
		bn_new(t);

		switch (operation) {
			case RSA_ENC:
			case RSA_SIG:
			case RSA_SIG_HASH:
				/* EB = 00 | FF | D. */
				bn_zero(m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PAD);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_DEC:
			case RSA_VER:
			case RSA_VER_HASH:
				/* EB = 00 | FF | D. */
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = RLC_ERR;
				}
				*p_len = 1;
				do {
					(*p_len)++;
					m_len--;
					bn_rsh(t, m, 8 * m_len);
					pad = (uint8_t)t->dp[0];
				} while (pad == 0 && m_len > 0);
				if (pad != RSA_PAD) {
					result = RLC_ERR;
				}
				bn_mod_2b(m, m, (k_len - *p_len) * 8);
				break;
		}
	}
	RLC_CATCH_ANY {
		result = RLC_ERR;
	}
	RLC_FINALLY {
		bn_free(t);
	}
	return result;
}


static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) {
	uint8_t *id, pad = 0;
	int len, result = RLC_OK;
	bn_t t;

	bn_null(t);

	RLC_TRY {
		bn_new(t);

		switch (operation) {
			case RSA_ENC:
				/* EB = 00 | 02 | PS | 00 | D. */
				bn_zero(m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PUB);

				*p_len = k_len - 3 - m_len;
				for (int i = 0; i < *p_len; i++) {
					bn_lsh(m, m, 8);
					do {
						rand_bytes(&pad, 1);
					} while (pad == 0);
					bn_add_dig(m, m, pad);
				}
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, 0);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_DEC:
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = RLC_ERR;
				}

				*p_len = m_len;
				m_len--;
				bn_rsh(t, m, 8 * m_len);
				pad = (uint8_t)t->dp[0];
				if (pad != RSA_PUB) {
					result = RLC_ERR;
				}
				do {
					m_len--;
					bn_rsh(t, m, 8 * m_len);
					pad = (uint8_t)t->dp[0];
				} while (pad != 0 && m_len > 0);
				/* Remove padding and trailing zero. */
				*p_len -= (m_len - 1);
				bn_mod_2b(m, m, (k_len - *p_len) * 8);
				break;
			case RSA_SIG:
				/* EB = 00 | 01 | PS | 00 | D. */
				id = hash_id(MD_MAP, &len);
				bn_zero(m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PRV);

				*p_len = k_len - 3 - m_len - len;
				for (int i = 0; i < *p_len; i++) {
					bn_lsh(m, m, 8);
					bn_add_dig(m, m, RSA_PAD);
				}
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, 0);
				bn_lsh(m, m, 8 * len);
				bn_read_bin(t, id, len);
				bn_add(m, m, t);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_SIG_HASH:
				/* EB = 00 | 01 | PS | 00 | D. */
				bn_zero(m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PRV);

				*p_len = k_len - 3 - m_len;
				for (int i = 0; i < *p_len; i++) {
					bn_lsh(m, m, 8);
					bn_add_dig(m, m, RSA_PAD);
				}
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, 0);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_VER:
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = RLC_ERR;
				}
				m_len--;
				bn_rsh(t, m, 8 * m_len);
				pad = (uint8_t)t->dp[0];
				if (pad != RSA_PRV) {
					result = RLC_ERR;
				}
				do {
					m_len--;
					bn_rsh(t, m, 8 * m_len);
					pad = (uint8_t)t->dp[0];
				} while (pad != 0 && m_len > 0);
				if (m_len == 0) {
					result = RLC_ERR;
				}
				/* Remove padding and trailing zero. */
				id = hash_id(MD_MAP, &len);
				m_len -= len;

				bn_rsh(t, m, m_len * 8);
				int r = 0;
				for (int i = 0; i < len; i++) {
					pad = (uint8_t)t->dp[0];
					r |= pad - id[len - i - 1];
					bn_rsh(t, t, 8);
				}
				*p_len = k_len - m_len;
				bn_mod_2b(m, m, m_len * 8);
				result = (r == 0 ? RLC_OK : RLC_ERR);
				break;
			case RSA_VER_HASH:
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = RLC_ERR;
				}
				m_len--;
				bn_rsh(t, m, 8 * m_len);
				pad = (uint8_t)t->dp[0];
				if (pad != RSA_PRV) {
					result = RLC_ERR;
				}
				do {
					m_len--;
					bn_rsh(t, m, 8 * m_len);
					pad = (uint8_t)t->dp[0];
				} while (pad != 0 && m_len > 0);
				if (m_len == 0) {
					result = RLC_ERR;
				}
				/* Remove padding and trailing zero. */
				*p_len = k_len - m_len;
				bn_mod_2b(m, m, m_len * 8);
				break;
		}
	}
	RLC_CATCH_ANY {
		result = RLC_ERR;
	}
	RLC_FINALLY {
		bn_free(t);
	}
	return result;
}


static int pad_pkcs2(bn_t m, int *p_len, int m_len, int k_len, int operation) {
        uint8_t pad, h1[RLC_MD_LEN], h2[RLC_MD_LEN];
        /* MSVC does not allow dynamic stack arrays */
        uint8_t *mask = RLC_ALLOCA(uint8_t, k_len);
	int result = RLC_OK;
	bn_t t;

	bn_null(t);

	RLC_TRY {
		bn_new(t);

		switch (operation) {
			case RSA_ENC:
				/* DB = lHash | PS | 01 | D. */
				md_map(h1, NULL, 0);
				bn_read_bin(m, h1, RLC_MD_LEN);
				*p_len = k_len - 2 * RLC_MD_LEN - 2 - m_len;
				bn_lsh(m, m, *p_len * 8);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, 0x01);
				/* Make room for the real message. */
				bn_lsh(m, m, m_len * 8);
				break;
			case RSA_ENC_FIN:
				/* EB = 00 | maskedSeed | maskedDB. */
				rand_bytes(h1, RLC_MD_LEN);
				md_mgf(mask, k_len - RLC_MD_LEN - 1, h1, RLC_MD_LEN);
				bn_read_bin(t, mask, k_len - RLC_MD_LEN - 1);
				for (int i = 0; i < t->used; i++) {
					m->dp[i] ^= t->dp[i];
				}
				bn_write_bin(mask, k_len - RLC_MD_LEN - 1, m);
				md_mgf(h2, RLC_MD_LEN, mask, k_len - RLC_MD_LEN - 1);
				for (int i = 0; i < RLC_MD_LEN; i++) {
					h1[i] ^= h2[i];
				}
				bn_read_bin(t, h1, RLC_MD_LEN);
				bn_lsh(t, t, 8 * (k_len - RLC_MD_LEN - 1));
				bn_add(t, t, m);
				bn_copy(m, t);
				break;
			case RSA_DEC:
				m_len = k_len - 1;
				bn_rsh(t, m, 8 * m_len);
				if (!bn_is_zero(t)) {
					result = RLC_ERR;
				}
				m_len -= RLC_MD_LEN;
				bn_rsh(t, m, 8 * m_len);
				bn_write_bin(h1, RLC_MD_LEN, t);
				bn_mod_2b(m, m, 8 * m_len);
				bn_write_bin(mask, m_len, m);
				md_mgf(h2, RLC_MD_LEN, mask, m_len);
				for (int i = 0; i < RLC_MD_LEN; i++) {
					h1[i] ^= h2[i];
				}
				md_mgf(mask, k_len - RLC_MD_LEN - 1, h1, RLC_MD_LEN);
				bn_read_bin(t, mask, k_len - RLC_MD_LEN - 1);
				for (int i = 0; i < t->used; i++) {
					m->dp[i] ^= t->dp[i];
				}
				m_len -= RLC_MD_LEN;
				bn_rsh(t, m, 8 * m_len);
				bn_write_bin(h2, RLC_MD_LEN, t);
				md_map(h1, NULL, 0);
				pad = 0;
				for (int i = 0; i < RLC_MD_LEN; i++) {
					pad |= h1[i] - h2[i];
				}
				if (result == RLC_OK) {
					result = (pad ? RLC_ERR : RLC_OK);
				}
				bn_mod_2b(m, m, 8 * m_len);
				*p_len = bn_size_bin(m);
				(*p_len)--;
				bn_rsh(t, m, *p_len * 8);
				if (bn_cmp_dig(t, 1) != RLC_EQ) {
					result = RLC_ERR;
				}
				bn_mod_2b(m, m, *p_len * 8);
				*p_len = k_len - *p_len;
				break;
			case RSA_SIG:
			case RSA_SIG_HASH:
				/* M' = 00 00 00 00 00 00 00 00 | H(M). */
				bn_zero(m);
				bn_lsh(m, m, 64);
				/* Make room for the real message. */
				bn_lsh(m, m, RLC_MD_LEN * 8);
				break;
			case RSA_SIG_FIN:
				memset(mask, 0, 8);
				bn_write_bin(mask + 8, RLC_MD_LEN, m);
				md_map(h1, mask, RLC_MD_LEN + 8);
				bn_read_bin(m, h1, RLC_MD_LEN);
				md_mgf(mask, k_len - RLC_MD_LEN - 1, h1, RLC_MD_LEN);
				bn_read_bin(t, mask, k_len - RLC_MD_LEN - 1);
				t->dp[0] ^= 0x01;
				/* m_len is now the size in bits of the modulus. */
				bn_lsh(t, t, 8 * RLC_MD_LEN);
				bn_add(m, t, m);
				bn_lsh(m, m, 8);
				bn_add_dig(m, m, RSA_PSS);
				for (int i = m_len - 1; i < 8 * k_len; i++) {
					bn_set_bit(m, i, 0);
				}
				break;
			case RSA_VER:
			case RSA_VER_HASH:
				bn_mod_2b(t, m, 8);
				if (bn_cmp_dig(t, RSA_PSS) != RLC_EQ) {
					result = RLC_ERR;
				} else {
					for (int i = m_len; i < 8 * k_len; i++) {
						if (bn_get_bit(m, i) != 0) {
							result = RLC_ERR;
						}
					}
					bn_rsh(m, m, 8);
					bn_mod_2b(t, m, 8 * RLC_MD_LEN);
					bn_write_bin(h2, RLC_MD_LEN, t);
					bn_rsh(m, m, 8 * RLC_MD_LEN);
					bn_write_bin(h1, RLC_MD_LEN, t);
					md_mgf(mask, k_len - RLC_MD_LEN - 1, h1, RLC_MD_LEN);
					bn_read_bin(t, mask, k_len - RLC_MD_LEN - 1);
					for (int i = 0; i < t->used; i++) {
						m->dp[i] ^= t->dp[i];
					}
					m->dp[0] ^= 0x01;
					for (int i = m_len - 1; i < 8 * k_len; i++) {
						bn_set_bit(m, i - ((RLC_MD_LEN + 1) * 8), 0);
					}
					if (!bn_is_zero(m)) {
						result = RLC_ERR;
					}
					bn_read_bin(m, h2, RLC_MD_LEN);
					*p_len = k_len - RLC_MD_LEN;
				}
				break;
		}
	}
	RLC_CATCH_ANY {
		result = RLC_ERR;
	}
	RLC_FINALLY {
		bn_free(t);
	}

        RLC_FREE(mask);

	return result;
}


static int dissect_h245_MultilinkRequest ( tvbuff_t * tvb _U_ , int offset _U_ , asn1_ctx_t * actx _U_ , proto_tree * tree _U_ , int hf_index _U_ ) {
 offset = dissect_per_choice ( tvb , offset , actx , tree , hf_index , ett_h245_MultilinkRequest , MultilinkRequest_choice , NULL ) ;
 return offset ;
 }


static void virtio_net_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); dc->exit = virtio_net_device_exit; dc->props = virtio_net_properties; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); vdc->init = virtio_net_device_init; vdc->get_config = virtio_net_get_config; vdc->set_config = virtio_net_set_config; vdc->get_features = virtio_net_get_features; vdc->set_features = virtio_net_set_features; vdc->bad_features = virtio_net_bad_features; vdc->reset = virtio_net_reset; vdc->set_status = virtio_net_set_status; vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; }


void parseExpandedNodeId ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName ) {
 static const int * expandednodeid_mask [ ] = {
 & hf_opcua_nodeid_encodingmask , & hf_opcua_expandednodeid_mask_serverindex , & hf_opcua_expandednodeid_mask_namespaceuri , NULL }
 ;
 proto_item * ti ;
 proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , ett_opcua_expandednodeid , & ti , "%s: ExpandedNodeId" , szFieldName ) ;
 gint iOffset = * pOffset ;
 guint8 EncodingMask ;
 EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
 proto_tree_add_bitmask ( subtree , tvb , iOffset , hf_opcua_expandednodeid_mask , ett_opcua_expandednodeid_encodingmask , expandednodeid_mask , ENC_LITTLE_ENDIAN ) ;
 iOffset ++ ;
 switch ( EncodingMask & 0x0F ) {
 case 0x00 : proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 1 ;
 break ;
 case 0x01 : proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 1 ;
 proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 2 ;
 break ;
 case 0x02 : proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 2 ;
 proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 4 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 4 ;
 break ;
 case 0x03 : proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 2 ;
 parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_string ) ;
 break ;
 case 0x04 : proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 2 ;
 parseGuid ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_guid ) ;
 break ;
 case 0x05 : proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
 iOffset += 2 ;
 parseByteString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_bytestring ) ;
 break ;
 }
 ;
 if ( EncodingMask & NODEID_NAMESPACEURIFLAG ) {
 parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_NamespaceUri ) ;
 }
 if ( EncodingMask & NODEID_SERVERINDEXFLAG ) {
 parseUInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_ServerIndex ) ;
 }
 proto_item_set_end ( ti , tvb , iOffset ) ;
 * pOffset = iOffset ;
 }


int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
{
	if (name == NULL || strcmp((char*)node->name, name) == 0) {
		if (ns) {
			xmlNsPtr nsPtr = attr_find_ns(node);
			if (nsPtr) {
				return (strcmp((char*)nsPtr->href, ns) == 0);
			} else {
				return FALSE;
			}
		}
		return TRUE;
	}
	return FALSE;
}


read_fru_area_section(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
			uint32_t offset, uint32_t length, uint8_t *frubuf)
{
	static uint32_t fru_data_rqst_size = 20;
	uint32_t off = offset, tmp, finish;
	struct ipmi_rs * rsp;
	struct ipmi_rq req;
	uint8_t msg_data[4];

	if (offset > fru->size) {
		lprintf(LOG_ERR, "Read FRU Area offset incorrect: %d > %d",
			offset, fru->size);
		return -1;
	}

	finish = offset + length;
	if (finish > fru->size) {
		finish = fru->size;
		lprintf(LOG_NOTICE, "Read FRU Area length %d too large, "
			"Adjusting to %d",
			offset + length, finish - offset);
	}

	memset(&req, 0, sizeof(req));
	req.msg.netfn = IPMI_NETFN_STORAGE;
	req.msg.cmd = GET_FRU_DATA;
	req.msg.data = msg_data;
	req.msg.data_len = 4;

#ifdef LIMIT_ALL_REQUEST_SIZE
	if (fru_data_rqst_size > 16)
#else
	if (fru->access && fru_data_rqst_size > 16)
#endif
		fru_data_rqst_size = 16;
	do {
		tmp = fru->access ? off >> 1 : off;
		msg_data[0] = id;
		msg_data[1] = (uint8_t)(tmp & 0xff);
		msg_data[2] = (uint8_t)(tmp >> 8);
		tmp = finish - off;
		if (tmp > fru_data_rqst_size)
			msg_data[3] = (uint8_t)fru_data_rqst_size;
		else
			msg_data[3] = (uint8_t)tmp;

		rsp = intf->sendrecv(intf, &req);
		if (!rsp) {
			lprintf(LOG_NOTICE, "FRU Read failed");
			break;
		}
		if (rsp->ccode) {
			/* if we get C7 or C8  or CA return code then we requested too
			* many bytes at once so try again with smaller size */
			if (fru_cc_rq2big(rsp->ccode) && (--fru_data_rqst_size > FRU_BLOCK_SZ)) {
				lprintf(LOG_INFO,
					"Retrying FRU read with request size %d",
					fru_data_rqst_size);
				continue;
			}
			lprintf(LOG_NOTICE, "FRU Read failed: %s",
				val2str(rsp->ccode, completion_code_vals));
			break;
		}

		tmp = fru->access ? rsp->data[0] << 1 : rsp->data[0];
		memcpy((frubuf + off)-offset, rsp->data + 1, tmp);
		off += tmp;

		/* sometimes the size returned in the Info command
		* is too large.  return 0 so higher level function
		* still attempts to parse what was returned */
		if (tmp == 0 && off < finish)
			return 0;

	} while (off < finish);

	if (off < finish)
		return -1;

	return 0;
}


static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, const uint8_t *n_val) { OMAContext *oc = s->priv_data; uint64_t pos; uint32_t taglen, datalen; struct AVDES av_des; if (!enc_header || !n_val || size < OMA_ENC_HEADER_SIZE + oc->k_size + 4) return -1; pos = OMA_ENC_HEADER_SIZE + oc->k_size; if (!memcmp(&enc_header[pos], "EKB ", 4)) pos += 32; if (size < pos + 44) return -1; if (AV_RB32(&enc_header[pos]) != oc->rid) av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); taglen = AV_RB32(&enc_header[pos + 32]); datalen = AV_RB32(&enc_header[pos + 36]) >> 4; pos += 44; if (size - pos < taglen) return -1; pos += taglen; if (pos + (((uint64_t)datalen) << 4) > size) return -1; av_des_init(&av_des, n_val, 192, 1); while (datalen-- > 0) { av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); kset(s, oc->r_val, NULL, 16); if (!rprobe(s, enc_header, size, oc->r_val)) return 0; pos += 16; } return -1; }


static int ssl_verify_cert(struct tunnel *tunnel)
{
	int ret = -1;
	int cert_valid = 0;
	unsigned char digest[SHA256LEN];
	unsigned int len;
	struct x509_digest *elem;
	char digest_str[SHA256STRLEN], *subject, *issuer;
	char *line;
	int i;
	X509_NAME *subj;

	SSL_set_verify(tunnel->ssl_handle, SSL_VERIFY_PEER, NULL);

	X509 *cert = SSL_get_peer_certificate(tunnel->ssl_handle);
	if (cert == NULL) {
		log_error("Unable to get gateway certificate.\n");
		return 1;
	}

	subj = X509_get_subject_name(cert);

#ifdef HAVE_X509_CHECK_HOST
	// Use OpenSSL native host validation if v >= 1.0.2.
	// compare against gateway_host and correctly check return value
	// to fix piror Incorrect use of X509_check_host
	if (X509_check_host(cert, tunnel->config->gateway_host,
	                    0, 0, NULL) == 1)
		cert_valid = 1;
#else
	char common_name[FIELD_SIZE + 1];
	// Use explicit Common Name check if native validation not available.
	// Note: this will ignore Subject Alternative Name fields.
	if (subj
	    && X509_NAME_get_text_by_NID(subj, NID_commonName, common_name,
	                                 FIELD_SIZE) > 0
	    && strncasecmp(common_name, tunnel->config->gateway_host,
	                   FIELD_SIZE) == 0)
		cert_valid = 1;
#endif

	// Try to validate certificate using local PKI
	if (cert_valid
	    && SSL_get_verify_result(tunnel->ssl_handle) == X509_V_OK) {
		log_debug("Gateway certificate validation succeeded.\n");
		ret = 0;
		goto free_cert;
	}
	log_debug("Gateway certificate validation failed.\n");

	// If validation failed, check if cert is in the white list
	if (X509_digest(cert, EVP_sha256(), digest, &len) <= 0
	    || len != SHA256LEN) {
		log_error("Could not compute certificate sha256 digest.\n");
		goto free_cert;
	}
	// Encode digest in base16
	for (i = 0; i < SHA256LEN; i++)
		sprintf(&digest_str[2 * i], "%02x", digest[i]);
	digest_str[SHA256STRLEN - 1] = '\0';
	// Is it in whitelist?
	for (elem = tunnel->config->cert_whitelist; elem != NULL;
	     elem = elem->next)
		if (memcmp(digest_str, elem->data, SHA256STRLEN - 1) == 0)
			break;
	if (elem != NULL) { // break before end of loop
		log_debug("Gateway certificate digest found in white list.\n");
		ret = 0;
		goto free_cert;
	}

	subject = X509_NAME_oneline(subj, NULL, 0);
	issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);

	log_error("Gateway certificate validation failed, and the certificate digest in not in the local whitelist. If you trust it, rerun with:\n");
	log_error("    --trusted-cert %s\n", digest_str);
	log_error("or add this line to your config file:\n");
	log_error("    trusted-cert = %s\n", digest_str);
	log_error("Gateway certificate:\n");
	log_error("    subject:\n");
	for (line = strtok(subject, "/"); line != NULL;
	     line = strtok(NULL, "/"))
		log_error("        %s\n", line);
	log_error("    issuer:\n");
	for (line = strtok(issuer, "/"); line != NULL;
	     line = strtok(NULL, "/"))
		log_error("        %s\n", line);
	log_error("    sha256 digest:\n");
	log_error("        %s\n", digest_str);

free_cert:
	X509_free(cert);
	return ret;
}


static int rv10_decode_frame ( AVCodecContext * avctx , void * data , int * got_frame , AVPacket * avpkt ) {
 const uint8_t * buf = avpkt -> data ;
 int buf_size = avpkt -> size ;
 MpegEncContext * s = avctx -> priv_data ;
 int i ;
 AVFrame * pict = data ;
 int slice_count ;
 const uint8_t * slices_hdr = NULL ;
 av_dlog ( avctx , "*****frame %d size=%d\n" , avctx -> frame_number , buf_size ) ;
 if ( buf_size == 0 ) {
 return 0 ;
 }
 if ( ! avctx -> slice_count ) {
 slice_count = ( * buf ++ ) + 1 ;
 buf_size -- ;
 if ( ! slice_count || buf_size <= 8 * slice_count ) {
 av_log ( avctx , AV_LOG_ERROR , "Invalid slice count: %d.\n" , slice_count ) ;
 return AVERROR_INVALIDDATA ;
 }
 slices_hdr = buf + 4 ;
 buf += 8 * slice_count ;
 buf_size -= 8 * slice_count ;
 }
 else slice_count = avctx -> slice_count ;
 for ( i = 0 ;
 i < slice_count ;
 i ++ ) {
 unsigned offset = get_slice_offset ( avctx , slices_hdr , i ) ;
 int size , size2 ;
 if ( offset >= buf_size ) return AVERROR_INVALIDDATA ;
 if ( i + 1 == slice_count ) size = buf_size - offset ;
 else size = get_slice_offset ( avctx , slices_hdr , i + 1 ) - offset ;
 if ( i + 2 >= slice_count ) size2 = buf_size - offset ;
 else size2 = get_slice_offset ( avctx , slices_hdr , i + 2 ) - offset ;
 if ( size <= 0 || size2 <= 0 || offset + FFMAX ( size , size2 ) > buf_size ) return AVERROR_INVALIDDATA ;
 if ( rv10_decode_packet ( avctx , buf + offset , size , size2 ) > 8 * size ) i ++ ;
 }
 if ( s -> current_picture_ptr != NULL && s -> mb_y >= s -> mb_height ) {
 ff_er_frame_end ( & s -> er ) ;
 ff_MPV_frame_end ( s ) ;
 if ( s -> pict_type == AV_PICTURE_TYPE_B || s -> low_delay ) {
 * pict = s -> current_picture_ptr -> f ;
 }
 else if ( s -> last_picture_ptr != NULL ) {
 * pict = s -> last_picture_ptr -> f ;
 }
 if ( s -> last_picture_ptr || s -> low_delay ) {
 * got_frame = 1 ;
 ff_print_debug_info ( s , pict ) ;
 }
 s -> current_picture_ptr = NULL ;
 }
 return avpkt -> size ;
 }


int qemu_set_fd_handler2(int fd, IOCanReadHandler *fd_read_poll, IOHandler *fd_read, IOHandler *fd_write, void *opaque) { IOHandlerRecord *ioh; if (!fd_read && !fd_write) { QLIST_FOREACH(ioh, &io_handlers, next) { if (ioh->fd == fd) { ioh->deleted = 1; break; } } } else { QLIST_FOREACH(ioh, &io_handlers, next) { if (ioh->fd == fd) goto found; } ioh = g_malloc0(sizeof(IOHandlerRecord)); QLIST_INSERT_HEAD(&io_handlers, ioh, next); found: ioh->fd = fd; ioh->fd_read_poll = fd_read_poll; ioh->fd_read = fd_read; ioh->fd_write = fd_write; ioh->opaque = opaque; ioh->deleted = 0; qemu_notify_event(); } return 0; }


rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg)
{
    int32_t block[4];
    int32_t *bs = (magic != 0) ? &block[0] : &block[2];
    int blen = (magic != 0) ? sizeof(block) : sizeof(block) / 2;
    int32_t il;
    int32_t dl;
    int32_t * ei = NULL;
    size_t uc;
    size_t nb;
    rpmRC rc = RPMRC_FAIL;		/* assume failure */
    int xx;
    int32_t il_max = HEADER_TAGS_MAX;
    int32_t dl_max = HEADER_DATA_MAX;

    if (regionTag == RPMTAG_HEADERSIGNATURES) {
	il_max = 32;
	dl_max = 64 * 1024 * 1024;
    }

    memset(block, 0, sizeof(block));
    if ((xx = Freadall(fd, bs, blen)) != blen) {
	rasprintf(emsg,
		_("hdr size(%d): BAD, read returned %d"), blen, xx);
	goto exit;
    }
    if (magic && memcmp(block, rpm_header_magic, sizeof(rpm_header_magic))) {
	rasprintf(emsg, _("hdr magic: BAD"));
	goto exit;
    }
    il = ntohl(block[2]);
    if (hdrchkRange(il_max, il)) {
	rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
	goto exit;
    }
    dl = ntohl(block[3]);
    if (hdrchkRange(dl_max, dl)) {
	rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
	goto exit;
    }

    nb = (il * sizeof(struct entryInfo_s)) + dl;
    uc = sizeof(il) + sizeof(dl) + nb;
    ei = xmalloc(uc);
    ei[0] = block[2];
    ei[1] = block[3];
    if ((xx = Freadall(fd, (char *)&ei[2], nb)) != nb) {
	rasprintf(emsg, _("hdr blob(%zd): BAD, read returned %d"), nb, xx);
	goto exit;
    }

    if (regionTag == RPMTAG_HEADERSIGNATURES) {
	size_t sigSize = uc + sizeof(rpm_header_magic);
	size_t pad = (8 - (sigSize % 8)) % 8;
	size_t trc;
	if (pad && (trc = Freadall(fd, block, pad)) != pad) {
	    rasprintf(emsg, _("sigh pad(%zd): BAD, read %zd bytes"), pad, trc);
	    goto exit;
	}
    }

    rc = hdrblobInit(ei, uc, regionTag, exact_size, blob, emsg);

exit:
    if (rc != RPMRC_OK) {
	free(ei);
	blob->ei = NULL;
	if (emsg && *emsg && regionTag == RPMTAG_HEADERSIGNATURES) {
	    /* rstrscat() cannot handle overlap even if it claims so */
	    char *tmp = rstrscat(NULL, _("signature "), *emsg, NULL);
	    free(*emsg);
	    *emsg = tmp;
	}
    }

    return rc;
}


static int replace ( DYNAMIC_STRING * ds_str , const char * search_str , ulong search_len , const char * replace_str , ulong replace_len ) {
 DYNAMIC_STRING ds_tmp ;
 const char * start = strstr ( ds_str -> str , search_str ) ;
 if ( ! start ) return 1 ;
 init_dynamic_string_checked ( & ds_tmp , "" , ds_str -> length + replace_len , 256 ) ;
 dynstr_append_mem_checked ( & ds_tmp , ds_str -> str , start - ds_str -> str ) ;
 dynstr_append_mem_checked ( & ds_tmp , replace_str , replace_len ) ;
 dynstr_append_checked ( & ds_tmp , start + search_len ) ;
 dynstr_set_checked ( ds_str , ds_tmp . str ) ;
 dynstr_free ( & ds_tmp ) ;
 return 0 ;
 }


static inline void tqi_idct_put ( TqiContext * t , AVFrame * frame , int16_t ( * block ) [ 64 ] ) {
 MpegEncContext * s = & t -> s ;
 int linesize = frame -> linesize [ 0 ] ;
 uint8_t * dest_y = frame -> data [ 0 ] + ( s -> mb_y * 16 * linesize ) + s -> mb_x * 16 ;
 uint8_t * dest_cb = frame -> data [ 1 ] + ( s -> mb_y * 8 * frame -> linesize [ 1 ] ) + s -> mb_x * 8 ;
 uint8_t * dest_cr = frame -> data [ 2 ] + ( s -> mb_y * 8 * frame -> linesize [ 2 ] ) + s -> mb_x * 8 ;
 ff_ea_idct_put_c ( dest_y , linesize , block [ 0 ] ) ;
 ff_ea_idct_put_c ( dest_y + 8 , linesize , block [ 1 ] ) ;
 ff_ea_idct_put_c ( dest_y + 8 * linesize , linesize , block [ 2 ] ) ;
 ff_ea_idct_put_c ( dest_y + 8 * linesize + 8 , linesize , block [ 3 ] ) ;
 if ( ! ( s -> avctx -> flags & CODEC_FLAG_GRAY ) ) {
 ff_ea_idct_put_c ( dest_cb , frame -> linesize [ 1 ] , block [ 4 ] ) ;
 ff_ea_idct_put_c ( dest_cr , frame -> linesize [ 2 ] , block [ 5 ] ) ;
 }
 }


static void record_recent_object ( struct object * obj , const char * name , void * data ) {
 sha1_array_append ( & recent_objects , obj -> oid . hash ) ;
 }


static int dissect_h245_INTEGER_1_4095 ( tvbuff_t * tvb _U_ , int offset _U_ , asn1_ctx_t * actx _U_ , proto_tree * tree _U_ , int hf_index _U_ ) {
 offset = dissect_per_constrained_integer ( tvb , offset , actx , tree , hf_index , 1U , 4095U , NULL , FALSE ) ;
 return offset ;
 }


void proto_reg_handoff_zbee_zcl_appl_stats ( void ) {
 dissector_handle_t appl_stats_handle ;
 appl_stats_handle = find_dissector ( ZBEE_PROTOABBREV_ZCL_APPLSTATS ) ;
 dissector_add_uint ( "zbee.zcl.cluster" , ZBEE_ZCL_CID_APPLIANCE_STATISTICS , appl_stats_handle ) ;
 zbee_zcl_init_cluster ( proto_zbee_zcl_appl_stats , ett_zbee_zcl_appl_stats , ZBEE_ZCL_CID_APPLIANCE_STATISTICS , hf_zbee_zcl_appl_stats_attr_id , hf_zbee_zcl_appl_stats_srv_rx_cmd_id , hf_zbee_zcl_appl_stats_srv_tx_cmd_id , NULL ) ;
 }