/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>

typedef struct Icmp {
	uint8_t vihl;				/* Version and header length */
	uint8_t tos;				/* Type of service */
	uint8_t length[2];			/* packet length */
	uint8_t id[2];				/* Identification */
	uint8_t frag[2];			/* Fragment information */
	uint8_t ttl;				/* Time to live */
	uint8_t proto;				/* Protocol */
	uint8_t ipcksum[2];			/* Header checksum */
	uint8_t src[4];				/* Ip source */
	uint8_t dst[4];				/* Ip destination */
	uint8_t type;
	uint8_t code;
	uint8_t cksum[2];
	uint8_t icmpid[2];
	uint8_t seq[2];
	uint8_t data[1];
} Icmp;

enum {							/* Packet Types */
	EchoReply = 0,
	Unreachable = 3,
	SrcQuench = 4,
	Redirect = 5,
	EchoRequest = 8,
	TimeExceed = 11,
	InParmProblem = 12,
	Timestamp = 13,
	TimestampReply = 14,
	InfoRequest = 15,
	InfoReply = 16,
	AddrMaskRequest = 17,
	AddrMaskReply = 18,

	Maxtype = 18,
};

enum {
	MinAdvise = 24,				/* minimum needed for us to advise another protocol */
};

char *icmpnames[Maxtype + 1] = {
	[EchoReply] "EchoReply",
	[Unreachable] "Unreachable",
	[SrcQuench] "SrcQuench",
	[Redirect] "Redirect",
	[EchoRequest] "EchoRequest",
	[TimeExceed] "TimeExceed",
	[InParmProblem] "InParmProblem",
	[Timestamp] "Timestamp",
	[TimestampReply] "TimestampReply",
	[InfoRequest] "InfoRequest",
	[InfoReply] "InfoReply",
	[AddrMaskRequest] "AddrMaskRequest",
	[AddrMaskReply] "AddrMaskReply  ",
};

enum {
	IP_ICMPPROTO = 1,
	ICMP_IPSIZE = 20,
	ICMP_HDRSIZE = 8,
};

enum {
	InMsgs,
	InErrors,
	OutMsgs,
	CsumErrs,
	LenErrs,
	HlenErrs,

	Nstats,
};

static char *statnames[Nstats] = {
	[InMsgs] "InMsgs",
	[InErrors] "InErrors",
	[OutMsgs] "OutMsgs",
	[CsumErrs] "CsumErrs",
	[LenErrs] "LenErrs",
	[HlenErrs] "HlenErrs",
};

typedef struct Icmppriv Icmppriv;
struct Icmppriv {
	uint32_t stats[Nstats];

	/* message counts */
	uint32_t in[Maxtype + 1];
	uint32_t out[Maxtype + 1];
};

static void icmpkick(void *x, struct block *);

static void icmpcreate(struct conv *c)
{
	c->rq = qopen(64 * 1024, Qmsg, 0, c);
	c->wq = qbypass(icmpkick, c);
}

void icmpconnect(struct conv *c, char **argv, int argc)
{
	Fsstdconnect(c, argv, argc);
	Fsconnected(c, 0);
}

extern int icmpstate(struct conv *c, char *state, int n)
{
	return snprintf(state, n, "%s qin %d qout %d\n",
					"Datagram",
					c->rq ? qlen(c->rq) : 0, c->wq ? qlen(c->wq) : 0);
}

void icmpannounce(struct conv *c, char **argv, int argc)
{
	Fsstdannounce(c, argv, argc);
	Fsconnected(c, NULL);
}

extern void icmpclose(struct conv *c)
{
	qclose(c->rq);
	qclose(c->wq);
	ipmove(c->laddr, IPnoaddr);
	ipmove(c->raddr, IPnoaddr);
	c->lport = 0;
}

static void icmpkick(void *x, struct block *bp)
{
	struct conv *c = x;
	Icmp *p;
	Icmppriv *ipriv;

	if (bp == NULL)
		return;

	bp = pullupblock(bp, ICMP_IPSIZE + ICMP_HDRSIZE);
	if (bp == 0)
		return;
	p = (Icmp *) (bp->rp);
	p->vihl = IP_VER4;
	ipriv = c->p->priv;
	if (p->type <= Maxtype)
		ipriv->out[p->type]++;

	v6tov4(p->dst, c->raddr);
	v6tov4(p->src, c->laddr);
	p->proto = IP_ICMPPROTO;
	hnputs(p->icmpid, c->lport);
	memset(p->cksum, 0, sizeof(p->cksum));
	hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
	ipriv->stats[OutMsgs]++;
	netlog(c->p->f, Logicmp,
	       "icmp output: Type %s (%d,%d), To %V, TTL %d, ID %d, SEQ %d\n",
	       icmpnames[MIN(p->type, Maxtype)],
	       p->type, p->code, p->dst, p->ttl, nhgets(p->icmpid), nhgets(p->seq));
	ipoput4(c->p->f, bp, 0, c->ttl, c->tos, NULL);
}

extern void icmpttlexceeded(struct Fs *f, uint8_t * ia, struct block *bp)
{
	struct block *nbp;
	Icmp *p, *np;

	p = (Icmp *) bp->rp;

	netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src);
	nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8, MEM_WAIT);
	nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
	np = (Icmp *) nbp->rp;
	np->vihl = IP_VER4;
	memmove(np->dst, p->src, sizeof(np->dst));
	v6tov4(np->src, ia);
	memmove(np->data, bp->rp, ICMP_IPSIZE + 8);
	np->type = TimeExceed;
	np->code = 0;
	np->proto = IP_ICMPPROTO;
	hnputs(np->icmpid, 0);
	hnputs(np->seq, 0);
	memset(np->cksum, 0, sizeof(np->cksum));
	hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
	ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, NULL);

}

static void icmpunreachable(struct Fs *f, struct block *bp, int code, int seq)
{
	struct block *nbp;
	Icmp *p, *np;
	int i;
	uint8_t addr[IPaddrlen];

	p = (Icmp *) bp->rp;

	/* only do this for unicast sources and destinations */
	v4tov6(addr, p->dst);
	i = ipforme(f, addr);
	if ((i & Runi) == 0)
		return;
	v4tov6(addr, p->src);
	i = ipforme(f, addr);
	if (i != 0 && (i & Runi) == 0)
		return;

	/* TODO: Clean this up or remove it.  This is for things like UDP port
	 * unreachable.  But we might not be UDP, due to how the code is built.
	 * Check the UDP netlog if you see this. */
	netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
	nbp = block_alloc(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8, MEM_WAIT);
	nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
	np = (Icmp *) nbp->rp;
	np->vihl = IP_VER4;
	memmove(np->dst, p->src, sizeof(np->dst));
	memmove(np->src, p->dst, sizeof(np->src));
	memmove(np->data, bp->rp, ICMP_IPSIZE + 8);
	np->type = Unreachable;
	np->code = code;
	np->proto = IP_ICMPPROTO;
	hnputs(np->icmpid, 0);
	hnputs(np->seq, seq);
	memset(np->cksum, 0, sizeof(np->cksum));
	hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
	ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
}

extern void icmpnoconv(struct Fs *f, struct block *bp)
{
	icmpunreachable(f, bp, 3, 0);
}

extern void icmpcantfrag(struct Fs *f, struct block *bp, int mtu)
{
	icmpunreachable(f, bp, 4, mtu);
}

static void goticmpkt(struct Proto *icmp, struct block *bp)
{
	struct conv **c, *s;
	Icmp *p;
	uint8_t dst[IPaddrlen];
	uint16_t recid;

	p = (Icmp *) bp->rp;
	v4tov6(dst, p->src);
	recid = nhgets(p->icmpid);

	for (c = icmp->conv; *c; c++) {
		s = *c;
		if (s->lport == recid)
			if (ipcmp(s->raddr, dst) == 0) {
				bp = concatblock(bp);
				if (bp != NULL)
					qpass(s->rq, bp);
				return;
			}
	}
	freeblist(bp);
}

static struct block *mkechoreply(struct Proto *icmp, struct block *bp)
{
	Icmp *q;
	uint8_t ip[4];

	/* we're repurposing bp to send it back out.  we need to remove any inbound
	 * checksum flags (which were saying the HW did the checksum) and any other
	 * metadata.  We might need to fill in some of the metadata too. */
	block_reset_metadata(bp);
	q = (Icmp *) bp->rp;
	q->vihl = IP_VER4;
	memmove(ip, q->src, sizeof(q->dst));
	memmove(q->src, q->dst, sizeof(q->src));
	memmove(q->dst, ip, sizeof(q->dst));
	q->type = EchoReply;
	memset(q->cksum, 0, sizeof(q->cksum));
	hnputs(q->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
	netlog(icmp->f, Logicmp,
	       "icmp echo reply: To %V, TTL %d, ID %d, SEQ %d\n",
	       q->dst, q->ttl, nhgets(q->icmpid), nhgets(q->seq));
	return bp;
}

static char *unreachcode[] = {
	[0] "net unreachable",
	[1] "host unreachable",
	[2] "protocol unreachable",
	[3] "port unreachable",
	[4] "fragmentation needed and DF set",
	[5] "source route failed",
};

static void icmpiput(struct Proto *icmp, struct Ipifc *unused, struct block *bp)
{
	int n, iplen;
	Icmp *p;
	struct block *r;
	struct Proto *pr;
	char *msg;
	char m2[128];
	Icmppriv *ipriv;

	bp = pullupblock(bp, ICMP_IPSIZE + ICMP_HDRSIZE);
	if (bp == NULL)
		return;

	ipriv = icmp->priv;

	ipriv->stats[InMsgs]++;

	p = (Icmp *) bp->rp;
	/* The ID and SEQ are only for Echo Request and Reply, but close enough. */
	netlog(icmp->f, Logicmp,
	       "icmp input: Type %s (%d,%d), From %V, TTL %d, ID %d, SEQ %d\n",
	       icmpnames[MIN(p->type, Maxtype)],
	       p->type, p->code, p->src, p->ttl, nhgets(p->icmpid), nhgets(p->seq));
	n = blocklen(bp);
	if (n < ICMP_IPSIZE + ICMP_HDRSIZE) {
		/* pullupblock should fail if dlen < size.  b->len >= b->dlen. */
		panic("We did a pullupblock and thought we had enough!");
		ipriv->stats[InErrors]++;
		ipriv->stats[HlenErrs]++;
		netlog(icmp->f, Logicmp, "icmp hlen %d\n", n);
		goto raise;
	}
	iplen = nhgets(p->length);
	if (iplen > n || (iplen % 1)) {
		ipriv->stats[LenErrs]++;
		ipriv->stats[InErrors]++;
		netlog(icmp->f, Logicmp, "icmp length %d\n", iplen);
		goto raise;
	}
	if (ptclcsum(bp, ICMP_IPSIZE, iplen - ICMP_IPSIZE)) {
		ipriv->stats[InErrors]++;
		ipriv->stats[CsumErrs]++;
		netlog(icmp->f, Logicmp, "icmp checksum error\n");
		goto raise;
	}
	if (p->type <= Maxtype)
		ipriv->in[p->type]++;

	switch (p->type) {
		case EchoRequest:
			if (iplen < n)
				bp = trimblock(bp, 0, iplen);
			r = mkechoreply(icmp, bp);
			ipriv->out[EchoReply]++;
			ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, NULL);
			break;
		case Unreachable:
			if (p->code > 5)
				msg = unreachcode[1];
			else
				msg = unreachcode[p->code];

			bp->rp += ICMP_IPSIZE + ICMP_HDRSIZE;
			if (blocklen(bp) < MinAdvise) {
				ipriv->stats[LenErrs]++;
				goto raise;
			}
			p = (Icmp *) bp->rp;
			pr = Fsrcvpcolx(icmp->f, p->proto);
			if (pr != NULL && pr->advise != NULL) {
				(*pr->advise) (pr, bp, msg);
				return;
			}

			bp->rp -= ICMP_IPSIZE + ICMP_HDRSIZE;
			goticmpkt(icmp, bp);
			break;
		case TimeExceed:
			if (p->code == 0) {
				snprintf(m2, sizeof(m2), "ttl exceeded at %V", p->src);

				bp->rp += ICMP_IPSIZE + ICMP_HDRSIZE;
				if (blocklen(bp) < MinAdvise) {
					ipriv->stats[LenErrs]++;
					goto raise;
				}
				p = (Icmp *) bp->rp;
				pr = Fsrcvpcolx(icmp->f, p->proto);
				if (pr != NULL && pr->advise != NULL) {
					(*pr->advise) (pr, bp, m2);
					return;
				}
				bp->rp -= ICMP_IPSIZE + ICMP_HDRSIZE;
			}

			goticmpkt(icmp, bp);
			break;
		default:
			goticmpkt(icmp, bp);
			break;
	}
	return;

raise:
	freeblist(bp);
}

void icmpadvise(struct Proto *icmp, struct block *bp, char *msg)
{
	struct conv **c, *s;
	Icmp *p;
	uint8_t dst[IPaddrlen];
	uint16_t recid;

	p = (Icmp *) bp->rp;
	v4tov6(dst, p->dst);
	recid = nhgets(p->icmpid);

	for (c = icmp->conv; *c; c++) {
		s = *c;
		if (s->lport == recid)
			if (ipcmp(s->raddr, dst) == 0) {
				qhangup(s->rq, msg);
				qhangup(s->wq, msg);
				break;
			}
	}
	freeblist(bp);
}

int icmpstats(struct Proto *icmp, char *buf, int len)
{
	Icmppriv *priv;
	char *p, *e;
	int i;

	priv = icmp->priv;
	p = buf;
	e = p + len;
	for (i = 0; i < Nstats; i++)
		p = seprintf(p, e, "%s: %u\n", statnames[i], priv->stats[i]);
	for (i = 0; i <= Maxtype; i++) {
		if (icmpnames[i])
			p = seprintf(p, e, "%s: %u %u\n", icmpnames[i], priv->in[i],
						 priv->out[i]);
		else
			p = seprintf(p, e, "%d: %u %u\n", i, priv->in[i], priv->out[i]);
	}
	return p - buf;
}

void icmpinit(struct Fs *fs)
{
	struct Proto *icmp;

	icmp = kzmalloc(sizeof(struct Proto), 0);
	icmp->priv = kzmalloc(sizeof(Icmppriv), 0);
	icmp->name = "icmp";
	icmp->connect = icmpconnect;
	icmp->announce = icmpannounce;
	icmp->state = icmpstate;
	icmp->create = icmpcreate;
	icmp->close = icmpclose;
	icmp->rcv = icmpiput;
	icmp->stats = icmpstats;
	icmp->ctl = NULL;
	icmp->advise = icmpadvise;
	icmp->gc = NULL;
	icmp->ipproto = IP_ICMPPROTO;
	icmp->nc = 128;
	icmp->ptclsize = 0;

	Fsproto(fs, icmp);
}
