/*
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* \summary: IP printer */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "netdissect-stdinc.h"

#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"

#include "ip.h"
#include "ipproto.h"


static const struct tok ip_option_values[] = {
    { IPOPT_EOL, "EOL" },
    { IPOPT_NOP, "NOP" },
    { IPOPT_TS, "timestamp" },
    { IPOPT_SECURITY, "security" },
    { IPOPT_RR, "RR" },
    { IPOPT_SSRR, "SSRR" },
    { IPOPT_LSRR, "LSRR" },
    { IPOPT_RA, "RA" },
    { IPOPT_RFC1393, "traceroute" },
    { 0, NULL }
};

/*
 * print the recorded route in an IP RR, LSRR or SSRR option.
 */
static int
ip_printroute(netdissect_options *ndo,
              const u_char *cp, u_int length)
{
	u_int ptr;
	u_int len;

	if (length < 3) {
		ND_PRINT(" [bad length %u]", length);
		return (0);
	}
	if ((length + 1) & 3)
		ND_PRINT(" [bad length %u]", length);
	ptr = GET_U_1(cp + 2) - 1;
	if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
		ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2));

	for (len = 3; len < length; len += 4) {
		ND_TCHECK_4(cp + len);	/* Needed to print the IP addresses */
		ND_PRINT(" %s", GET_IPADDR_STRING(cp + len));
		if (ptr > len)
			ND_PRINT(",");
	}
	return (0);

trunc:
	return (-1);
}

/*
 * If source-routing is present and valid, return the final destination.
 * Otherwise, return IP destination.
 *
 * This is used for UDP and TCP pseudo-header in the checksum
 * calculation.
 */
static uint32_t
ip_finddst(netdissect_options *ndo,
           const struct ip *ip)
{
	u_int length;
	u_int len;
	const u_char *cp;

	cp = (const u_char *)(ip + 1);
	length = IP_HL(ip) * 4;
	if (length < sizeof(struct ip))
		goto trunc;
	length -= sizeof(struct ip);

	for (; length != 0; cp += len, length -= len) {
		int tt;

		tt = GET_U_1(cp);
		if (tt == IPOPT_EOL)
			break;
		else if (tt == IPOPT_NOP)
			len = 1;
		else {
			len = GET_U_1(cp + 1);
			if (len < 2)
				break;
		}
		if (length < len)
			goto trunc;
		ND_TCHECK_LEN(cp, len);
		switch (tt) {

		case IPOPT_SSRR:
		case IPOPT_LSRR:
			if (len < 7)
				break;
			return (GET_IPV4_TO_NETWORK_ORDER(cp + len - 4));
		}
	}
trunc:
	return (GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst));
}

/*
 * Compute a V4-style checksum by building a pseudoheader.
 */
uint16_t
nextproto4_cksum(netdissect_options *ndo,
                 const struct ip *ip, const uint8_t *data,
                 u_int len, u_int covlen, uint8_t next_proto)
{
	struct phdr {
		uint32_t src;
		uint32_t dst;
		uint8_t mbz;
		uint8_t proto;
		uint16_t len;
	} ph;
	struct cksum_vec vec[2];

	/* pseudo-header.. */
	ph.len = htons((uint16_t)len);
	ph.mbz = 0;
	ph.proto = next_proto;
	ph.src = GET_IPV4_TO_NETWORK_ORDER(ip->ip_src);
	if (IP_HL(ip) == 5)
		ph.dst = GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst);
	else
		ph.dst = ip_finddst(ndo, ip);

	vec[0].ptr = (const uint8_t *)(void *)&ph;
	vec[0].len = sizeof(ph);
	vec[1].ptr = data;
	vec[1].len = covlen;
	return (in_cksum(vec, 2));
}

static int
ip_printts(netdissect_options *ndo,
           const u_char *cp, u_int length)
{
	u_int ptr;
	u_int len;
	u_int hoplen;
	const char *type;

	if (length < 4) {
		ND_PRINT("[bad length %u]", length);
		return (0);
	}
	ND_PRINT(" TS{");
	hoplen = ((GET_U_1(cp + 3) & 0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
	if ((length - 4) & (hoplen-1))
		ND_PRINT("[bad length %u]", length);
	ptr = GET_U_1(cp + 2) - 1;
	len = 0;
	if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
		ND_PRINT("[bad ptr %u]", GET_U_1(cp + 2));
	switch (GET_U_1(cp + 3)&0xF) {
	case IPOPT_TS_TSONLY:
		ND_PRINT("TSONLY");
		break;
	case IPOPT_TS_TSANDADDR:
		ND_PRINT("TS+ADDR");
		break;
	case IPOPT_TS_PRESPEC:
		ND_PRINT("PRESPEC");
		break;
	default:
		ND_PRINT("[bad ts type %u]", GET_U_1(cp + 3)&0xF);
		goto done;
	}

	type = " ";
	for (len = 4; len < length; len += hoplen) {
		if (ptr == len)
			type = " ^ ";
		ND_TCHECK_LEN(cp + len, hoplen);
		ND_PRINT("%s%u@%s", type, GET_BE_U_4(cp + len + hoplen - 4),
			  hoplen!=8 ? "" : GET_IPADDR_STRING(cp + len));
		type = " ";
	}

done:
	ND_PRINT("%s", ptr == len ? " ^ " : "");

	if (GET_U_1(cp + 3) >> 4)
		ND_PRINT(" [%u hops not recorded]} ", GET_U_1(cp + 3)>>4);
	else
		ND_PRINT("}");
	return (0);

trunc:
	return (-1);
}

/*
 * print IP options.
   If truncated return -1, else 0.
 */
static int
ip_optprint(netdissect_options *ndo,
            const u_char *cp, u_int length)
{
	u_int option_len;
	const char *sep = "";

	for (; length > 0; cp += option_len, length -= option_len) {
		u_int option_code;

		ND_PRINT("%s", sep);
		sep = ",";

		option_code = GET_U_1(cp);

		ND_PRINT("%s",
		          tok2str(ip_option_values,"unknown %u",option_code));

		if (option_code == IPOPT_NOP ||
                    option_code == IPOPT_EOL)
			option_len = 1;

		else {
			option_len = GET_U_1(cp + 1);
			if (option_len < 2) {
				ND_PRINT(" [bad length %u]", option_len);
				return 0;
			}
		}

		if (option_len > length) {
			ND_PRINT(" [bad length %u]", option_len);
			return 0;
		}

		ND_TCHECK_LEN(cp, option_len);

		switch (option_code) {
		case IPOPT_EOL:
			return 0;

		case IPOPT_TS:
			if (ip_printts(ndo, cp, option_len) == -1)
				goto trunc;
			break;

		case IPOPT_RR:       /* fall through */
		case IPOPT_SSRR:
		case IPOPT_LSRR:
			if (ip_printroute(ndo, cp, option_len) == -1)
				goto trunc;
			break;

		case IPOPT_RA:
			if (option_len < 4) {
				ND_PRINT(" [bad length %u]", option_len);
				break;
			}
			ND_TCHECK_1(cp + 3);
			if (GET_BE_U_2(cp + 2) != 0)
				ND_PRINT(" value %u", GET_BE_U_2(cp + 2));
			break;

		case IPOPT_NOP:       /* nothing to print - fall through */
		case IPOPT_SECURITY:
		default:
			break;
		}
	}
	return 0;

trunc:
	return -1;
}

#define IP_RES 0x8000

static const struct tok ip_frag_values[] = {
        { IP_MF,        "+" },
        { IP_DF,        "DF" },
	{ IP_RES,       "rsvd" }, /* The RFC3514 evil ;-) bit */
        { 0,            NULL }
};


/*
 * print an IP datagram.
 */
void
ip_print(netdissect_options *ndo,
	 const u_char *bp,
	 u_int length)
{
	const struct ip *ip;
	u_int off;
	u_int hlen;
	u_int len;
	struct cksum_vec vec[1];
	uint8_t ip_tos, ip_ttl, ip_proto;
	uint16_t sum, ip_sum;
	const char *p_name;
	int truncated = 0;

	ndo->ndo_protocol = "ip";
	ip = (const struct ip *)bp;
	if (IP_V(ip) != 4) { /* print version and fail if != 4 */
	    if (IP_V(ip) == 6)
	      ND_PRINT("IP6, wrong link-layer encapsulation");
	    else
	      ND_PRINT("IP%u", IP_V(ip));
	    nd_print_invalid(ndo);
	    return;
	}
	if (!ndo->ndo_eflag)
		ND_PRINT("IP ");

	ND_TCHECK_SIZE(ip);
	if (length < sizeof (struct ip)) {
		ND_PRINT("truncated-ip %u", length);
		return;
	}
	hlen = IP_HL(ip) * 4;
	if (hlen < sizeof (struct ip)) {
		ND_PRINT("bad-hlen %u", hlen);
		return;
	}

	len = GET_BE_U_2(ip->ip_len);
	if (length < len)
		ND_PRINT("truncated-ip - %u bytes missing! ",
			len - length);
	if (len < hlen) {
#ifdef GUESS_TSO
            if (len) {
                ND_PRINT("bad-len %u", len);
                return;
            }
            else {
                /* we guess that it is a TSO send */
                len = length;
            }
#else
            ND_PRINT("bad-len %u", len);
            return;
#endif /* GUESS_TSO */
	}

	/*
	 * Cut off the snapshot length to the end of the IP payload.
	 */
	if (!nd_push_snaplen(ndo, bp, len)) {
		(*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
			"%s: can't push snaplen on buffer stack", __func__);
	}

	len -= hlen;

	off = GET_BE_U_2(ip->ip_off);

        ip_proto = GET_U_1(ip->ip_p);

        if (ndo->ndo_vflag) {
            ip_tos = GET_U_1(ip->ip_tos);
            ND_PRINT("(tos 0x%x", ip_tos);
            /* ECN bits */
            switch (ip_tos & 0x03) {

            case 0:
                break;

            case 1:
                ND_PRINT(",ECT(1)");
                break;

            case 2:
                ND_PRINT(",ECT(0)");
                break;

            case 3:
                ND_PRINT(",CE");
                break;
            }

            ip_ttl = GET_U_1(ip->ip_ttl);
            if (ip_ttl >= 1)
                ND_PRINT(", ttl %u", ip_ttl);

	    /*
	     * for the firewall guys, print id, offset.
             * On all but the last stick a "+" in the flags portion.
	     * For unfragmented datagrams, note the don't fragment flag.
	     */
	    ND_PRINT(", id %u, offset %u, flags [%s], proto %s (%u)",
                         GET_BE_U_2(ip->ip_id),
                         (off & IP_OFFMASK) * 8,
                         bittok2str(ip_frag_values, "none", off & (IP_RES|IP_DF|IP_MF)),
                         tok2str(ipproto_values, "unknown", ip_proto),
                         ip_proto);

            ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len));

            if ((hlen - sizeof(struct ip)) > 0) {
                ND_PRINT(", options (");
                if (ip_optprint(ndo, (const u_char *)(ip + 1),
                    hlen - sizeof(struct ip)) == -1) {
                        ND_PRINT(" [truncated-option]");
			truncated = 1;
                }
                ND_PRINT(")");
            }

	    if (!ndo->ndo_Kflag && (const u_char *)ip + hlen <= ndo->ndo_snapend) {
	        vec[0].ptr = (const uint8_t *)(const void *)ip;
	        vec[0].len = hlen;
	        sum = in_cksum(vec, 1);
		if (sum != 0) {
		    ip_sum = GET_BE_U_2(ip->ip_sum);
		    ND_PRINT(", bad cksum %x (->%x)!", ip_sum,
			     in_cksum_shouldbe(ip_sum, sum));
		}
	    }

	    ND_PRINT(")\n    ");
	    if (truncated) {
		ND_PRINT("%s > %s: ",
			 GET_IPADDR_STRING(ip->ip_src),
			 GET_IPADDR_STRING(ip->ip_dst));
		nd_print_trunc(ndo);
		nd_pop_packet_info(ndo);
		return;
	    }
	}

	/*
	 * If this is fragment zero, hand it to the next higher
	 * level protocol.  Let them know whether there are more
	 * fragments.
	 */
	if ((off & IP_OFFMASK) == 0) {
		uint8_t nh = GET_U_1(ip->ip_p);

		if (nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
		    nh != IPPROTO_SCTP && nh != IPPROTO_DCCP) {
			ND_PRINT("%s > %s: ",
				     GET_IPADDR_STRING(ip->ip_src),
				     GET_IPADDR_STRING(ip->ip_dst));
		}
		/*
		 * Do a bounds check before calling ip_demux_print().
		 * At least the header data is required.
		 */
		if (!ND_TTEST_LEN((const u_char *)ip, hlen)) {
			ND_PRINT(" [remaining caplen(%u) < header length(%u)]",
				 ND_BYTES_AVAILABLE_AFTER((const u_char *)ip),
				 hlen);
			nd_trunc_longjmp(ndo);
		}
		ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4,
			       off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
	} else {
		/*
		 * Ultra quiet now means that all this stuff should be
		 * suppressed.
		 */
		if (ndo->ndo_qflag > 1) {
			nd_pop_packet_info(ndo);
			return;
		}

		/*
		 * This isn't the first frag, so we're missing the
		 * next level protocol header.  print the ip addr
		 * and the protocol.
		 */
		ND_PRINT("%s > %s:", GET_IPADDR_STRING(ip->ip_src),
		          GET_IPADDR_STRING(ip->ip_dst));
		if (!ndo->ndo_nflag && (p_name = netdb_protoname(ip_proto)) != NULL)
			ND_PRINT(" %s", p_name);
		else
			ND_PRINT(" ip-proto-%u", ip_proto);
	}
	nd_pop_packet_info(ndo);
	return;

trunc:
	nd_print_trunc(ndo);
}

void
ipN_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
	ndo->ndo_protocol = "ipn";
	if (length < 1) {
		ND_PRINT("truncated-ip %u", length);
		return;
	}

	switch (GET_U_1(bp) & 0xF0) {
	case 0x40:
		ip_print(ndo, bp, length);
		break;
	case 0x60:
		ip6_print(ndo, bp, length);
		break;
	default:
		ND_PRINT("unknown ip %u", (GET_U_1(bp) & 0xF0) >> 4);
		break;
	}
}
