/*
 * Encrypting tunnel for userv-ipif tunnels, header file
 */
/*
 * This file is part of ipif, part of userv-utils
 *
 * Copyright 1996-2013 Ian Jackson <ijackson@chiark.greenend.org.uk>
 * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
 * Copyright 1999,2003
 *    Chancellor Masters and Scholars of the University of Cambridge
 * Copyright 2010 Tony Finch <fanf@dotat.at>
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with userv-utils; if not, see http://www.gnu.org/licenses/.
 */

#ifndef MECHS_H
#define MECHS_H

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/utsname.h>

struct buffer {
  unsigned char *base;
  unsigned char *start;
  size_t size;
};

struct mechdata;

typedef void mes_functype(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_io);
typedef void mds_functype(struct mechdata **md_r);

typedef void menc_functype(struct mechdata *md, struct buffer*);
typedef const char *mdec_functype(struct mechdata *md, struct buffer*);

struct mechanism {
  const char *name;
  mes_functype *encsetup;
  mds_functype *decsetup;
  menc_functype *encode;
  mdec_functype *decode;
};

#include "automech.h"

extern const struct mechanism *const mechanismlists[];

/* setup function may call getarg_xxx functions and then
 * reads/writes key material to/from fd
 * 
 * setup_in function may increase maxprefix and maxsuffix
 * code functions modify buffer in place
 * decode function returns 0 meaning packet decoded ok,
 *  "" meaning discard it quietly, or message to print for verbose discard
 */
  
const char *getarg_string(void);
unsigned long getarg_ulong(void);

#define PROGRAM "udptunnel-forwarder"
extern char programid[];

void *buf_append(struct buffer *buf, size_t amount);
void *buf_prepend(struct buffer *buf, size_t amount);
void *buf_unappend(struct buffer *buf, size_t amount); /* may give 0 */
void *buf_unprepend(struct buffer *buf, size_t amount); /* may give 0 */

void sysfail(const char *msg);
void fail(const char *msg);
void sysdiag(const char *msg);
void diag(const char *msg);

extern const char *const *argv;

time_t now(void);
void *xmalloc(size_t sz);
void get_random(void *ptr, size_t sz);
void random_key(void *ptr, size_t sz);
void write_must(int fd, const void *p_in, int sz, const char *what);
void read_must(int fd, void *p_in, int sz, const char *what);

void arg_assert_fail(const char *msg);
#define arg_assert(v)  (v ? (void)0 : arg_assert_fail(#v))

#define XMALLOC(variable) ((variable)= xmalloc(sizeof(*(variable))))

#define BUF_UNSOMEEND(var,buf,sz,whichend) \
 do { var= whichend(buf,sz); if (!var) return "message truncated"; } while(0)
#define BUF_UNAPPEND(var,buf,sz) BUF_UNSOMEEND(var,buf,sz,buf_unappend)
#define BUF_UNPREPEND(var,buf,sz) BUF_UNSOMEEND(var,buf,sz,buf_unprepend)

#define STANDARD_MECHANISMLIST(mechstring,filename) \
 const struct mechanism mechlist_##filename []= {    \
   STANDARD_MECHANISM(mechstring,filename)          \
   { 0 }                                            \
 };

#define STANDARD_MECHANISM(mechstring,mechname) \
 { mechstring, mes_##mechname, mds_##mechname, menc_##mechname, mdec_##mechname },
 
#endif
