/*
 * multilink.c - support routines for multilink.
 *
 * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. The name(s) of the authors of this software must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission.
 *
 * 3. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by Paul Mackerras
 *     <paulus@samba.org>".
 *
 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <netdb.h>
#include <errno.h>
#include <signal.h>
#include <netinet/in.h>
#include <unistd.h>

#include "pppd.h"
#include "fsm.h"
#include "lcp.h"
#include "tdb.h"

bool endpoint_specified;	/* user gave explicit endpoint discriminator */
char *bundle_id;		/* identifier for our bundle */
char *blinks_id;		/* key for the list of links */
bool doing_multilink;		/* multilink was enabled and agreed to */
bool multilink_master;		/* we own the multilink bundle */

extern TDB_CONTEXT *pppdb;
extern char db_key[];

static void make_bundle_links __P((int append));
static void remove_bundle_link __P((void));
static void iterate_bundle_links __P((void (*func) __P((char *))));

static int get_default_epdisc __P((struct epdisc *));
static int parse_num __P((char *str, const char *key, int *valp));
static int owns_unit __P((TDB_DATA pid, int unit));

#define set_ip_epdisc(ep, addr) do {	\
	ep->length = 4;			\
	ep->value[0] = addr >> 24;	\
	ep->value[1] = addr >> 16;	\
	ep->value[2] = addr >> 8;	\
	ep->value[3] = addr;		\
} while (0)

#define LOCAL_IP_ADDR(addr)						  \
	(((addr) & 0xff000000) == 0x0a000000		/* 10.x.x.x */	  \
	 || ((addr) & 0xfff00000) == 0xac100000		/* 172.16.x.x */  \
	 || ((addr) & 0xffff0000) == 0xc0a80000)	/* 192.168.x.x */

#define process_exists(n)	(kill((n), 0) == 0 || errno != ESRCH)

void
mp_check_options()
{
	lcp_options *wo = &lcp_wantoptions[0];
	lcp_options *ao = &lcp_allowoptions[0];

	doing_multilink = 0;
	if (!multilink)
		return;
	/* if we're doing multilink, we have to negotiate MRRU */
	if (!wo->neg_mrru) {
		/* mrru not specified, default to mru */
		wo->mrru = wo->mru;
		wo->neg_mrru = 1;
	}
	ao->mrru = ao->mru;
	ao->neg_mrru = 1;

	if (!wo->neg_endpoint && !noendpoint) {
		/* get a default endpoint value */
		wo->neg_endpoint = get_default_epdisc(&wo->endpoint);
	}
}

/*
 * Make a new bundle or join us to an existing bundle
 * if we are doing multilink.
 */
int
mp_join_bundle()
{
	lcp_options *go = &lcp_gotoptions[0];
	lcp_options *ho = &lcp_hisoptions[0];
	lcp_options *ao = &lcp_allowoptions[0];
	int unit, pppd_pid;
	int l, mtu;
	char *p;
	TDB_DATA key, pid, rec;

	if (doing_multilink) {
		/* have previously joined a bundle */
		if (!go->neg_mrru || !ho->neg_mrru) {
			notice("oops, didn't get multilink on renegotiation");
			lcp_close(0, "multilink required");
			return 0;
		}
		/* XXX should check the peer_authname and ho->endpoint
		   are the same as previously */
		return 0;
	}

	if (!go->neg_mrru || !ho->neg_mrru) {
		/* not doing multilink */
		if (go->neg_mrru)
			notice("oops, multilink negotiated only for receive");
		mtu = ho->neg_mru? ho->mru: PPP_MRU;
		if (mtu > ao->mru)
			mtu = ao->mru;
		if (demand) {
			/* already have a bundle */
			cfg_bundle(0, 0, 0, 0);
			netif_set_mtu(0, mtu);
			return 0;
		}
		make_new_bundle(0, 0, 0, 0);
		set_ifunit(1);
		netif_set_mtu(0, mtu);
		return 0;
	}

	doing_multilink = 1;

	/*
	 * Find the appropriate bundle or join a new one.
	 * First we make up a name for the bundle.
	 * The length estimate is worst-case assuming every
	 * character has to be quoted.
	 */
	l = 4 * strlen(peer_authname) + 10;
	if (ho->neg_endpoint)
		l += 3 * ho->endpoint.length + 8;
	if (bundle_name)
		l += 3 * strlen(bundle_name) + 2;
	bundle_id = malloc(l);
	if (bundle_id == 0)
		novm("bundle identifier");

	p = bundle_id;
	p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname);
	if (ho->neg_endpoint || bundle_name)
		*p++ = '/';
	if (ho->neg_endpoint)
		p += slprintf(p, bundle_id+l-p, "%s",
			      epdisc_to_str(&ho->endpoint));
	if (bundle_name)
		p += slprintf(p, bundle_id+l-p, "/%v", bundle_name);

	/* Make the key for the list of links belonging to the bundle */
	l = p - bundle_id;
	blinks_id = malloc(l + 7);
	if (blinks_id == NULL)
		novm("bundle links key");
	slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7);

	/*
	 * For demand mode, we only need to configure the bundle
	 * and attach the link.
	 */
	mtu = MIN(ho->mrru, ao->mru);
	if (demand) {
		cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
		netif_set_mtu(0, mtu);
		script_setenv("BUNDLE", bundle_id + 7, 1);
		return 0;
	}

	/*
	 * Check if the bundle ID is already in the database.
	 */
	unit = -1;
	lock_db();
	key.dptr = bundle_id;
	key.dsize = p - bundle_id;
	pid = tdb_fetch(pppdb, key);
	if (pid.dptr != NULL) {
		/* bundle ID exists, see if the pppd record exists */
		rec = tdb_fetch(pppdb, pid);
		if (rec.dptr != NULL && rec.dsize > 0) {
			/* make sure the string is null-terminated */
			rec.dptr[rec.dsize-1] = 0;
			/* parse the interface number */
			parse_num(rec.dptr, "IFNAME=ppp", &unit);
			/* check the pid value */
			if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
			    || !process_exists(pppd_pid)
			    || !owns_unit(pid, unit))
				unit = -1;
			free(rec.dptr);
		}
		free(pid.dptr);
	}

	if (unit >= 0) {
		/* attach to existing unit */
		if (bundle_attach(unit)) {
			set_ifunit(0);
			script_setenv("BUNDLE", bundle_id + 7, 0);
			make_bundle_links(1);
			unlock_db();
			info("Link attached to %s", ifname);
			return 1;
		}
		/* attach failed because bundle doesn't exist */
	}

	/* we have to make a new bundle */
	make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
	set_ifunit(1);
	netif_set_mtu(0, mtu);
	script_setenv("BUNDLE", bundle_id + 7, 1);
	make_bundle_links(0);
	unlock_db();
	info("New bundle %s created", ifname);
	multilink_master = 1;
	return 0;
}

void mp_exit_bundle()
{
	lock_db();
	remove_bundle_link();
	unlock_db();
}

static void sendhup(char *str)
{
	int pid;

	if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) {
		if (debug)
			dbglog("sending SIGHUP to process %d", pid);
		kill(pid, SIGHUP);
	}
}

void mp_bundle_terminated()
{
	TDB_DATA key;

	bundle_terminating = 1;
	upper_layers_down(0);
	notice("Connection terminated.");
	print_link_stats();
	if (!demand) {
		remove_pidfiles();
		script_unsetenv("IFNAME");
	}

	lock_db();
	destroy_bundle();
	iterate_bundle_links(sendhup);
	key.dptr = blinks_id;
	key.dsize = strlen(blinks_id);
	tdb_delete(pppdb, key);
	unlock_db();
	
new_phase(PHASE_DEAD);
}

static void make_bundle_links(int append)
{
	TDB_DATA key, rec;
	char *p;
	char entry[32];
	int l;

	key.dptr = blinks_id;
	key.dsize = strlen(blinks_id);
	slprintf(entry, sizeof(entry), "%s;", db_key);
	p = entry;
	if (append) {
		rec = tdb_fetch(pppdb, key);
		if (rec.dptr != NULL && rec.dsize > 0) {
			rec.dptr[rec.dsize-1] = 0;
			if (strstr(rec.dptr, db_key) != NULL) {
				/* already in there? strange */
				warn("link entry already exists in tdb");
				return;
			}
			l = rec.dsize + strlen(entry);
			p = malloc(l);
			if (p == NULL)
				novm("bundle link list");
			slprintf(p, l, "%s%s", rec.dptr, entry);
		} else {
			warn("bundle link list not found");
		}
		if (rec.dptr != NULL)
			free(rec.dptr);
	}
	rec.dptr = p;
	rec.dsize = strlen(p) + 1;
	if (tdb_store(pppdb, key, rec, TDB_REPLACE))
		error("couldn't %s bundle link list",
		      append? "update": "create");
	if (p != entry)
		free(p);
}

static void remove_bundle_link()
{
	TDB_DATA key, rec;
	char entry[32];
	char *p, *q;
	int l;

	key.dptr = blinks_id;
	key.dsize = strlen(blinks_id);
	slprintf(entry, sizeof(entry), "%s;", db_key);

	rec = tdb_fetch(pppdb, key);
	if (rec.dptr == NULL || rec.dsize <= 0) {
		if (rec.dptr != NULL)
			free(rec.dptr);
		return;
	}
	rec.dptr[rec.dsize-1] = 0;
	p = strstr(rec.dptr, entry);
	if (p != NULL) {
		q = p + strlen(entry);
		l = strlen(q) + 1;
		memmove(p, q, l);
		rec.dsize = p - rec.dptr + l;
		if (tdb_store(pppdb, key, rec, TDB_REPLACE))
			error("couldn't update bundle link list (removal)");
	}
	free(rec.dptr);
}

static void iterate_bundle_links(void (*func)(char *))
{
	TDB_DATA key, rec, pp;
	char *p, *q;

	key.dptr = blinks_id;
	key.dsize = strlen(blinks_id);
	rec = tdb_fetch(pppdb, key);
	if (rec.dptr == NULL || rec.dsize <= 0) {
		error("bundle link list not found (iterating list)");
		if (rec.dptr != NULL)
			free(rec.dptr);
		return;
	}
	p = rec.dptr;
	p[rec.dsize-1] = 0;
	while ((q = strchr(p, ';')) != NULL) {
		*q = 0;
		key.dptr = p;
		key.dsize = q - p;
		pp = tdb_fetch(pppdb, key);
		if (pp.dptr != NULL && pp.dsize > 0) {
			pp.dptr[pp.dsize-1] = 0;
			func(pp.dptr);
		}
		if (pp.dptr != NULL)
			free(pp.dptr);
		p = q + 1;
	}
	free(rec.dptr);
}

static int
parse_num(str, key, valp)
     char *str;
     const char *key;
     int *valp;
{
	char *p, *endp;
	int i;

	p = strstr(str, key);
	if (p != 0) {
		p += strlen(key);
		i = strtol(p, &endp, 10);
		if (endp != p && (*endp == 0 || *endp == ';')) {
			*valp = i;
			return 1;
		}
	}
	return 0;
}

/*
 * Check whether the pppd identified by `key' still owns ppp unit `unit'.
 */
static int
owns_unit(key, unit)
     TDB_DATA key;
     int unit;
{
	char ifkey[32];
	TDB_DATA kd, vd;
	int ret = 0;

	slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
	kd.dptr = ifkey;
	kd.dsize = strlen(ifkey);
	vd = tdb_fetch(pppdb, kd);
	if (vd.dptr != NULL) {
		ret = vd.dsize == key.dsize
			&& memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
		free(vd.dptr);
	}
	return ret;
}

static int
get_default_epdisc(ep)
     struct epdisc *ep;
{
	char *p;
	struct hostent *hp;
	u_int32_t addr;

	/* First try for an ethernet MAC address */
	p = get_first_ethernet();
	if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) {
		ep->class = EPD_MAC;
		ep->length = 6;
		return 1;
	}

	/* see if our hostname corresponds to a reasonable IP address */
	hp = gethostbyname(hostname);
	if (hp != NULL) {
		addr = *(u_int32_t *)hp->h_addr;
		if (!bad_ip_adrs(addr)) {
			addr = ntohl(addr);
			if (!LOCAL_IP_ADDR(addr)) {
				ep->class = EPD_IP;
				set_ip_epdisc(ep, addr);
				return 1;
			}
		}
	}

	return 0;
}

/*
 * epdisc_to_str - make a printable string from an endpoint discriminator.
 */

static char *endp_class_names[] = {
    "null", "local", "IP", "MAC", "magic", "phone"
};

char *
epdisc_to_str(ep)
     struct epdisc *ep;
{
	static char str[MAX_ENDP_LEN*3+8];
	u_char *p = ep->value;
	int i, mask = 0;
	char *q, c, c2;

	if (ep->class == EPD_NULL && ep->length == 0)
		return "null";
	if (ep->class == EPD_IP && ep->length == 4) {
		u_int32_t addr;

		GETLONG(addr, p);
		slprintf(str, sizeof(str), "IP:%I", htonl(addr));
		return str;
	}

	c = ':';
	c2 = '.';
	if (ep->class == EPD_MAC && ep->length == 6)
		c2 = ':';
	else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0)
		mask = 3;
	q = str;
	if (ep->class <= EPD_PHONENUM)
		q += slprintf(q, sizeof(str)-1, "%s",
			      endp_class_names[ep->class]);
	else
		q += slprintf(q, sizeof(str)-1, "%d", ep->class);
	c = ':';
	for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) {
		if ((i & mask) == 0) {
			*q++ = c;
			c = c2;
		}
		q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]);
	}
	return str;
}

static int hexc_val(int c)
{
	if (c >= 'a')
		return c - 'a' + 10;
	if (c >= 'A')
		return c - 'A' + 10;
	return c - '0';
}

int
str_to_epdisc(ep, str)
     struct epdisc *ep;
     char *str;
{
	int i, l;
	char *p, *endp;

	for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) {
		int sl = strlen(endp_class_names[i]);
		if (strncasecmp(str, endp_class_names[i], sl) == 0) {
			str += sl;
			break;
		}
	}
	if (i > EPD_PHONENUM) {
		/* not a class name, try a decimal class number */
		i = strtol(str, &endp, 10);
		if (endp == str)
			return 0;	/* can't parse class number */
		str = endp;
	}
	ep->class = i;
	if (*str == 0) {
		ep->length = 0;
		return 1;
	}
	if (*str != ':' && *str != '.')
		return 0;
	++str;

	if (i == EPD_IP) {
		u_int32_t addr;
		i = parse_dotted_ip(str, &addr);
		if (i == 0 || str[i] != 0)
			return 0;
		set_ip_epdisc(ep, addr);
		return 1;
	}
	if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) {
		ep->length = 6;
		return 1;
	}

	p = str;
	for (l = 0; l < MAX_ENDP_LEN; ++l) {
		if (*str == 0)
			break;
		if (p <= str)
			for (p = str; isxdigit(*p); ++p)
				;
		i = p - str;
		if (i == 0)
			return 0;
		ep->value[l] = hexc_val(*str++);
		if ((i & 1) == 0)
			ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++);
		if (*str == ':' || *str == '.')
			++str;
	}
	if (*str != 0 || (ep->class == EPD_MAC && l != 6))
		return 0;
	ep->length = l;
	return 1;
}

