TInt ThreadFunc(void* aData)
	{
	__UHEAP_MARK;
	
	CTrapCleanup* tc = CTrapCleanup::New();
	TTEST(tc != NULL);

	TThreadData* data = static_cast<TThreadData*> (aData);
	TTEST(data != NULL);

	RSqlDatabase db;
	TInt err = db.Open(KTestDbName1);
	TTEST2(err, KErrNone);
	
	err = db.SetIsolationLevel(data->iIsolationLevel);
	TTEST2(err, KErrNone);
		
	if(data->iTransType == 1)
		{
		_LIT8(KBeginTrans, "BEGIN");
		err = db.Exec(KBeginTrans);
		TTEST(err >= 0);
		}

	_LIT8(KInsertSql, "INSERT INTO A(Id) VALUES(");	
	for(TInt id=data->iLowRecNo;id<=data->iHighRecNo;++id)
		{
		TBuf8<128> sql(KInsertSql);
		sql.AppendNum((TInt64)id);
		sql.Append(_L(")"));
		err = KSqlErrBusy;
		const TInt KAttempts = 20;
		for(TInt i=0;i<KAttempts&&err==KSqlErrBusy;++i)
			{
			err = db.Exec(sql);
			if(err == KSqlErrBusy)
				{
				RThread th;
				TName name = th.Name();
				RDebug::Print(_L("!!!Database locked, Thread: %S, Attempt %d, column value %d\r\n"), &name, i + 1, id);
				User::After(1000000);
				}
			}
		TTEST2(err, 1);
		}

	if(data->iTransType == 1)
		{
		_LIT8(KCommitTrans, "COMMIT");
		err = db.Exec(KCommitTrans);
		TTEST(err >= 0);
		}

	db.Close();		
	delete tc;
	
	__UHEAP_MARKEND;
	
	return KErrNone;		
	}
TInt UpdateThreadFunc(void*)
	{
	__UHEAP_MARK;
	
	CTrapCleanup* tc = CTrapCleanup::New();
	TTEST(tc != NULL);

	RSqlDatabase db;
	TInt err = db.Open(KTestDbName1);
	TTEST2(err, KErrNone);

	RDebug::Print(_L("---:UpdThread: Set the isolation level to \"Read uncommitted\"\r\n"));
	err = db.SetIsolationLevel(RSqlDatabase::EReadUncommitted);
	TTEST2(err, KErrNone);

	RDebug::Print(_L("---:UpdThread: Begin a write transaction\r\n"));
	_LIT8(KBeginTransSql, "BEGIN IMMEDIATE TRANSACTION");
	err = db.Exec(KBeginTransSql);
	TTEST(err >= 0);

	RDebug::Print(_L("---:UpdThread: Update the record\r\n"));
	_LIT8(KUpdateSql, "UPDATE A SET Id = ");
	TBuf8<64> sql(KUpdateSql);
	sql.AppendNum((TInt64)KUpdatedValue);
	err = db.Exec(sql);
	TTEST(err >= 0);

	RDebug::Print(_L("---:UpdThread: Notify the main thread about the update\r\n"));
	MainThreadCrS.Signal();
	
	RDebug::Print(_L("---:UpdThread: Wait for permisson to continue...\r\n"));
	UpdateThreadCrS.Wait();

	RDebug::Print(_L("---:UpdThread: Rollback the update\r\n"));
	_LIT8(KRollBackTransSql, "ROLLBACK TRANSACTION");
	err = db.Exec(KRollBackTransSql);
	TTEST(err >= 0);

	RDebug::Print(_L("---:UpdThread: Notify the main thread about the rollback\r\n"));
	MainThreadCrS.Signal();
	
	db.Close();
	delete tc;
	
	__UHEAP_MARKEND;
	
	return KErrNone;		
	}
TInt TestThreadL(void*)
    {
        __UHEAP_MARK;
        
        CTrapCleanup* tc = CTrapCleanup::New();
        RFeatureControl rfc;
        TTEST2( rfc.Connect(), KErrNone );
        
        // During restore, feature manager server should be responsive and return KErrServerBusy for write request 
        TInt err = rfc.EnableFeature( TUid::Uid(0x00000001) );
        TTEST2(err, KErrServerBusy);
		
        // During restore, feature manager server should be responsive and NOT return KErrServerBusy for read request
		err = rfc.FeatureSupported( TUid::Uid(0x00000001) );
		TTEST(err != KErrServerBusy);
		
        rfc.Close();
        featMgrIsResponsive = ETrue;
        RDebug::Print(_L("+++:TestThread: Query and Modification completed\r\n"));
        MainThreadCrS.Signal();
        delete tc;
        
        __UHEAP_MARKEND;
        
        return KErrNone;
    }
Beispiel #4
0
static int
xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
{
	struct ip *ip = NULL;
#ifdef INET6
	struct ip6_hdr *ip6 = NULL;
#endif
	struct xid_map_entry *xmep;

	if (!TTEST(rp->rm_call.cb_vers))
		return (0);
	switch (IP_V((struct ip *)bp)) {
	case 4:
		ip = (struct ip *)bp;
		break;
#ifdef INET6
	case 6:
		ip6 = (struct ip6_hdr *)bp;
		break;
#endif
	default:
		return (1);
	}

	xmep = &xid_map[xid_map_next];

	if (++xid_map_next >= XIDMAPSIZE)
		xid_map_next = 0;

	xmep->xid = rp->rm_xid;
	if (ip) {
		xmep->ipver = 4;
		memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src));
		memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst));
	}
#ifdef INET6
	else if (ip6) {
		xmep->ipver = 6;
		memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src));
		memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
	}
#endif
	xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc);
	xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers);
	return (1);
}
Beispiel #5
0
EagleComplexType *et_parse_string(char *text)
{
    TTEST(text, "auto", ETAuto);
    TTEST(text, "any", ETAny);
    TTEST(text, "bool", ETInt1);
    TTEST(text, "byte", ETInt8);
    TTEST(text, "ubyte", ETUInt8);
    TTEST(text, "short", ETInt16);
    TTEST(text, "ushort", ETUInt16);
    TTEST(text, "int", ETInt32);
    TTEST(text, "uint", ETUInt32);
    TTEST(text, "long", ETInt64);
    TTEST(text, "ulong", ETUInt64);
    TTEST(text, "float", ETFloat);
    TTEST(text, "double", ETDouble);
    TTEST(text, "void", ETVoid);

    if(ty_is_name(text))
    {
        void *type = hst_get(&typedef_table, text, NULL, NULL);
        if(type)
            return type;

        if(ty_is_class(text))
            return ett_class_type(text);
        else if(ty_is_interface(text))
            return ett_interface_type(text);
        else if(ty_is_enum(text))
            return ett_enum_type(text);
        else
            return ett_struct_type(text);
    }

    if(pipe_is_type(text))
    {
        return ett_generic_type(text);
    }

    return NULL;
}
Beispiel #6
0
void
pgm_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2)
{
	register const struct pgm_header *pgm;
	register const struct ip *ip;
	register char ch;
	u_int16_t sport, dport;
	int addr_size;
	const void *nla;
	int nla_af;
#ifdef INET6
	char nla_buf[INET6_ADDRSTRLEN];
	register const struct ip6_hdr *ip6;
#else
	char nla_buf[INET_ADDRSTRLEN];
#endif
	u_int8_t opt_type, opt_len, flags1, flags2;
	u_int32_t seq, opts_len, len, offset;

	pgm = (struct pgm_header *)bp;
	ip = (struct ip *)bp2;
#ifdef INET6
	if (IP_V(ip) == 6)
		ip6 = (struct ip6_hdr *)bp2;
	else
		ip6 = NULL;
#else /* INET6 */
	if (IP_V(ip) == 6) {
		(void)printf("Can't handle IPv6");
		return;
	}
#endif /* INET6 */
	ch = '\0';
	if (!TTEST(pgm->pgm_dport)) {
#ifdef INET6
		if (ip6) {
			(void)printf("%s > %s: [|pgm]",
				ip6addr_string(&ip6->ip6_src),
				ip6addr_string(&ip6->ip6_dst));
			return;
		} else
#endif /* INET6 */
		{
			(void)printf("%s > %s: [|pgm]",
				ipaddr_string(&ip->ip_src),
				ipaddr_string(&ip->ip_dst));
			return;
		}
	}

	sport = EXTRACT_16BITS(&pgm->pgm_sport);
	dport = EXTRACT_16BITS(&pgm->pgm_dport);

#ifdef INET6
	if (ip6) {
		if (ip6->ip6_nxt == IPPROTO_PGM) {
			(void)printf("%s.%s > %s.%s: ",
				ip6addr_string(&ip6->ip6_src),
				tcpport_string(sport),
				ip6addr_string(&ip6->ip6_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	} else
#endif /*INET6*/
	{
		if (ip->ip_p == IPPROTO_PGM) {
			(void)printf("%s.%s > %s.%s: ",
				ipaddr_string(&ip->ip_src),
				tcpport_string(sport),
				ipaddr_string(&ip->ip_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	}

	TCHECK(*pgm);

        (void)printf("PGM, length %u", pgm->pgm_length);

        if (!vflag)
            return;

        if (length > pgm->pgm_length)
            length = pgm->pgm_length;

	(void)printf(" 0x%02x%02x%02x%02x%02x%02x ",
		     pgm->pgm_gsid[0],
                     pgm->pgm_gsid[1],
                     pgm->pgm_gsid[2],
		     pgm->pgm_gsid[3],
                     pgm->pgm_gsid[4],
                     pgm->pgm_gsid[5]);
	switch (pgm->pgm_type) {
	case PGM_SPM: {
	    struct pgm_spm *spm;

	    spm = (struct pgm_spm *)(pgm + 1);
	    TCHECK(*spm);

	    switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		nla_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		nla_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (spm + 1);
	    TCHECK2(*bp, addr_size);
	    nla = bp;
	    bp += addr_size;

	    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
	    (void)printf("SPM seq %u trail %u lead %u nla %s",
			 EXTRACT_32BITS(&spm->pgms_seq),
                         EXTRACT_32BITS(&spm->pgms_trailseq),
			 EXTRACT_32BITS(&spm->pgms_leadseq),
                         nla_buf);
	    break;
	}

	case PGM_POLL: {
	    struct pgm_poll *poll;

	    poll = (struct pgm_poll *)(pgm + 1);
	    TCHECK(*poll);
	    (void)printf("POLL seq %u round %u",
			 EXTRACT_32BITS(&poll->pgmp_seq),
                         EXTRACT_16BITS(&poll->pgmp_round));
	    bp = (u_char *) (poll + 1);
	    break;
	}
	case PGM_POLR: {
	    struct pgm_polr *polr;
	    u_int32_t ivl, rnd, mask;

	    polr = (struct pgm_polr *)(pgm + 1);
	    TCHECK(*polr);

	    switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		nla_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		nla_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (polr + 1);
	    TCHECK2(*bp, addr_size);
	    nla = bp;
	    bp += addr_size;

	    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));

	    TCHECK2(*bp, sizeof(u_int32_t));
	    ivl = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    TCHECK2(*bp, sizeof(u_int32_t));
	    rnd = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    TCHECK2(*bp, sizeof(u_int32_t));
	    mask = EXTRACT_32BITS(bp);
	    bp += sizeof(u_int32_t);

	    (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x "
			 "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq),
			 EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask);
	    break;
	}
	case PGM_ODATA: {
	    struct pgm_data *odata;

	    odata = (struct pgm_data *)(pgm + 1);
	    TCHECK(*odata);
	    (void)printf("ODATA trail %u seq %u",
			 EXTRACT_32BITS(&odata->pgmd_trailseq),
			 EXTRACT_32BITS(&odata->pgmd_seq));
	    bp = (u_char *) (odata + 1);
	    break;
	}

	case PGM_RDATA: {
	    struct pgm_data *rdata;

	    rdata = (struct pgm_data *)(pgm + 1);
	    TCHECK(*rdata);
	    (void)printf("RDATA trail %u seq %u",
			 EXTRACT_32BITS(&rdata->pgmd_trailseq),
			 EXTRACT_32BITS(&rdata->pgmd_seq));
	    bp = (u_char *) (rdata + 1);
	    break;
	}

	case PGM_NAK:
	case PGM_NULLNAK:
	case PGM_NCF: {
	    struct pgm_nak *nak;
	    const void *source, *group;
	    int source_af, group_af;
#ifdef INET6
	    char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN];
#else
	    char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN];
#endif

	    nak = (struct pgm_nak *)(pgm + 1);
	    TCHECK(*nak);

	    /*
	     * Skip past the source, saving info along the way
	     * and stopping if we don't have enough.
	     */
	    switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		source_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		source_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp = (u_char *) (nak + 1);
	    TCHECK2(*bp, addr_size);
	    source = bp;
	    bp += addr_size;

	    /*
	     * Skip past the group, saving info along the way
	     * and stopping if we don't have enough.
	     */
	    switch (EXTRACT_16BITS(bp)) {
	    case AFI_IP:
		addr_size = sizeof(struct in_addr);
		group_af = AF_INET;
		break;
#ifdef INET6
	    case AFI_IP6:
		addr_size = sizeof(struct in6_addr);
		group_af = AF_INET6;
		break;
#endif
	    default:
		goto trunc;
		break;
	    }
	    bp += (2 * sizeof(u_int16_t));
	    TCHECK2(*bp, addr_size);
	    group = bp;
	    bp += addr_size;

	    /*
	     * Options decoding can go here.
	     */
	    inet_ntop(source_af, source, source_buf, sizeof(source_buf));
	    inet_ntop(group_af, group, group_buf, sizeof(group_buf));
	    switch (pgm->pgm_type) {
		case PGM_NAK:
		    (void)printf("NAK ");
		    break;
		case PGM_NULLNAK:
		    (void)printf("NNAK ");
		    break;
		case PGM_NCF:
		    (void)printf("NCF ");
		    break;
		default:
                    break;
	    }
	    (void)printf("(%s -> %s), seq %u",
			 source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq));
	    break;
	}

	case PGM_ACK: {
	    struct pgm_ack *ack;

	    ack = (struct pgm_ack *)(pgm + 1);
	    TCHECK(*ack);
	    (void)printf("ACK seq %u",
			 EXTRACT_32BITS(&ack->pgma_rx_max_seq));
	    bp = (u_char *) (ack + 1);
	    break;
	}

	case PGM_SPMR:
	    (void)printf("SPMR");
	    break;

	default:
	    (void)printf("UNKNOWN type %0x02x", pgm->pgm_type);
	    break;

	}
	if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) {      

	    /*
	     * make sure there's enough for the first option header
	     */
	    if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) {
		(void)printf("[|OPT]");
		return;
	    } 

	    /*
	     * That option header MUST be an OPT_LENGTH option
	     * (see the first paragraph of section 9.1 in RFC 3208).
	     */
	    opt_type = *bp++;
	    if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) {
		(void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK);
		return;
	    }
	    opt_len = *bp++;
	    if (opt_len != 4) {
		(void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
		return;
	    }
	    opts_len = EXTRACT_16BITS(bp);
	    if (opts_len < 4) {
		(void)printf("[Bad total option length %u < 4]", opts_len);
		return;
	    }
	    bp += sizeof(u_int16_t);
	    (void)printf(" OPTS LEN %d", opts_len);
	    opts_len -= 4;

	    while (opts_len) {
		if (opts_len < PGM_MIN_OPT_LEN) {
		    (void)printf("[Total option length leaves no room for final option]");
		    return;
		}
		opt_type = *bp++;
		opt_len = *bp++;
		if (opt_len < PGM_MIN_OPT_LEN) {
		    (void)printf("[Bad option, length %u < %u]", opt_len,
		        PGM_MIN_OPT_LEN);
		    break;
		}
		if (opts_len < opt_len) {
		    (void)printf("[Total option length leaves no room for final option]");
		    return;
		}
		if (!TTEST2(*bp, opt_len - 2)) {
		    (void)printf(" [|OPT]");
		    return;
		} 

		switch (opt_type & PGM_OPT_MASK) {
		case PGM_OPT_LENGTH:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
			return;
		    }
		    (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp));
		    bp += sizeof(u_int16_t);
		    opts_len -= 4;
		    break;

		case PGM_OPT_FRAGMENT:
		    if (opt_len != 16) {
			(void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" FRAG seq %u off %u len %u", seq, offset, len);
		    opts_len -= 16;
		    break;

		case PGM_OPT_NAK_LIST:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    opt_len -= sizeof(u_int32_t);	/* option header */
		    (void)printf(" NAK LIST");
		    while (opt_len) {
			if (opt_len < sizeof(u_int32_t)) {
			    (void)printf("[Option length not a multiple of 4]");
			    return;
			}
			TCHECK2(*bp, sizeof(u_int32_t));
			(void)printf(" %u", EXTRACT_32BITS(bp));
			bp += sizeof(u_int32_t);
			opt_len -= sizeof(u_int32_t);
			opts_len -= sizeof(u_int32_t);
		    }
		    break;

		case PGM_OPT_JOIN:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" JOIN %u", seq);
		    opts_len -= 8;
		    break;

		case PGM_OPT_NAK_BO_IVL:
		    if (opt_len != 12) {
			(void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq);
		    opts_len -= 12;
		    break;

		case PGM_OPT_NAK_BO_RNG:
		    if (opt_len != 12) {
			(void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" BACKOFF max %u min %u", offset, seq);
		    opts_len -= 12;
		    break;

		case PGM_OPT_REDIRECT:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    switch (EXTRACT_16BITS(bp)) {
		    case AFI_IP:
			addr_size = sizeof(struct in_addr);
			nla_af = AF_INET;
			break;
#ifdef INET6
		    case AFI_IP6:
			addr_size = sizeof(struct in6_addr);
			nla_af = AF_INET6;
			break;
#endif
		    default:
			goto trunc;
			break;
		    }
		    bp += (2 * sizeof(u_int16_t));
		    if (opt_len != 4 + addr_size) {
			(void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len);
			return;
		    }
		    TCHECK2(*bp, addr_size);
		    nla = bp;
		    bp += addr_size;

		    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
		    (void)printf(" REDIRECT %s",  (char *)nla);
		    opts_len -= 4 + addr_size;
		    break;

		case PGM_OPT_PARITY_PRM:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY MAXTGS %u", len);
		    opts_len -= 8;
		    break;

		case PGM_OPT_PARITY_GRP:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    seq = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY GROUP %u", seq);
		    opts_len -= 8;
		    break;

		case PGM_OPT_CURR_TGSIZE:
		    if (opt_len != 8) {
			(void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    len = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    (void)printf(" PARITY ATGS %u", len);
		    opts_len -= 8;
		    break;

		case PGM_OPT_NBR_UNREACH:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" NBR_UNREACH");
		    opts_len -= 4;
		    break;

		case PGM_OPT_PATH_NLA:
		    (void)printf(" PATH_NLA [%d]", opt_len);
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;

		case PGM_OPT_SYN:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" SYN");
		    opts_len -= 4;
		    break;

		case PGM_OPT_FIN:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" FIN");
		    opts_len -= 4;
		    break;

		case PGM_OPT_RST:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_RST option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" RST");
		    opts_len -= 4;
		    break;

		case PGM_OPT_CR:
		    (void)printf(" CR");
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;

		case PGM_OPT_CRQST:
		    if (opt_len != 4) {
			(void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len);
			return;
		    }
		    flags1 = *bp++;
		    flags2 = *bp++;
		    (void)printf(" CRQST");
		    opts_len -= 4;
		    break;

		case PGM_OPT_PGMCC_DATA:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    switch (EXTRACT_16BITS(bp)) {
		    case AFI_IP:
			addr_size = sizeof(struct in_addr);
			nla_af = AF_INET;
			break;
#ifdef INET6
		    case AFI_IP6:
			addr_size = sizeof(struct in6_addr);
			nla_af = AF_INET6;
			break;
#endif
		    default:
			goto trunc;
			break;
		    }
		    bp += (2 * sizeof(u_int16_t));
		    if (opt_len != 12 + addr_size) {
			(void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len);
			return;
		    }
		    TCHECK2(*bp, addr_size);
		    nla = bp;
		    bp += addr_size;

		    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
		    (void)printf(" PGMCC DATA %u %s", offset, (char*)nla);
		    opts_len -= 16;
		    break;

		case PGM_OPT_PGMCC_FEEDBACK:
		    flags1 = *bp++;
		    flags2 = *bp++;
		    offset = EXTRACT_32BITS(bp);
		    bp += sizeof(u_int32_t);
		    switch (EXTRACT_16BITS(bp)) {
		    case AFI_IP:
			addr_size = sizeof(struct in_addr);
			nla_af = AF_INET;
			break;
#ifdef INET6
		    case AFI_IP6:
			addr_size = sizeof(struct in6_addr);
			nla_af = AF_INET6;
			break;
#endif
		    default:
			goto trunc;
			break;
		    }
		    bp += (2 * sizeof(u_int16_t));
		    if (opt_len != 12 + addr_size) {
			(void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len);
			return;
		    }
		    TCHECK2(*bp, addr_size);
		    nla = bp;
		    bp += addr_size;

		    inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
		    (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla);
		    opts_len -= 16;
		    break;

		default:
		    (void)printf(" OPT_%02X [%d] ", opt_type, opt_len);
		    bp += opt_len;
		    opts_len -= opt_len;
		    break;
		}

		if (opt_type & PGM_OPT_END)
		    break;
	     }
	}

	(void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length));

	return;

trunc:
	fputs("[|pgm]", stdout);
	if (ch != '\0')
		putchar('>');
}
Beispiel #7
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2, int fragmented)
{
        register const struct tcphdr *tp;
        register const struct ip *ip;
        register u_char flags;
        register u_int hlen;
        register char ch;
        u_int16_t sport, dport, win, urp;
        u_int32_t seq, ack, thseq, thack;
        u_int utoval;
        int threv;
#ifdef INET6
        register const struct ip6_hdr *ip6;
#endif

        tp = (struct tcphdr *)bp;
        ip = (struct ip *)bp2;
#ifdef INET6
        if (IP_V(ip) == 6)
                ip6 = (struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
#endif /*INET6*/
        ch = '\0';
        if (!TTEST(tp->th_dport)) {
                (void)printf("%s > %s: [|tcp]",
                             ipaddr_string(&ip->ip_src),
                             ipaddr_string(&ip->ip_dst));
                return;
        }

        sport = EXTRACT_16BITS(&tp->th_sport);
        dport = EXTRACT_16BITS(&tp->th_dport);

        hlen = TH_OFF(tp) * 4;

        /*
	 * If data present, header length valid, and NFS port used,
	 * assume NFS.
	 * Pass offset of data plus 4 bytes for RPC TCP msg length
	 * to NFS print routines.
	 */
	if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
	    (length - hlen) >= 4) {
		u_char *fraglenp;
		u_int32_t fraglen;
		register struct sunrpc_msg *rp;
		enum sunrpc_msg_type direction;

		fraglenp = (u_char *)tp + hlen;
		if (TTEST2(*fraglenp, 4)) {
			fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
			if (fraglen > (length - hlen) - 4)
				fraglen = (length - hlen) - 4;
			rp = (struct sunrpc_msg *)(fraglenp + 4);
			if (TTEST(rp->rm_direction)) {
				direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
				if (dport == NFS_PORT &&
				    direction == SUNRPC_CALL) {
					nfsreq_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
				if (sport == NFS_PORT &&
				    direction == SUNRPC_REPLY) {
					nfsreply_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
			}
                }
        }
#ifdef INET6
        if (ip6) {
                if (ip6->ip6_nxt == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ip6addr_string(&ip6->ip6_src),
                                     tcpport_string(sport),
                                     ip6addr_string(&ip6->ip6_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        } else
#endif /*INET6*/
        {
                if (ip->ip_p == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ipaddr_string(&ip->ip_src),
                                     tcpport_string(sport),
                                     ipaddr_string(&ip->ip_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        }

        if (hlen < sizeof(*tp)) {
                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        TCHECK(*tp);

        seq = EXTRACT_32BITS(&tp->th_seq);
        ack = EXTRACT_32BITS(&tp->th_ack);
        win = EXTRACT_16BITS(&tp->th_win);
        urp = EXTRACT_16BITS(&tp->th_urp);

        if (qflag) {
                (void)printf("tcp %d", length - hlen);
                if (hlen > length) {
                        (void)printf(" [bad hdr length %u - too long, > %u]",
                                     hlen, length);
                }
                return;
        }

        flags = tp->th_flags;
        printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!Sflag && (flags & TH_ACK)) {
                register struct tcp_seq_hash *th;
                const void *src, *dst;
                register int rev;
                struct tha tha;
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
#ifdef INET6
                rev = 0;
                if (ip6) {
                        src = &ip6->ip6_src;
                        dst = &ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.dst, src, sizeof ip6->ip6_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.src, src, sizeof ip6->ip6_src);
                                tha.port = sport << 16 | dport;
                        }
                } else {
                        /*
                         * Zero out the tha structure; the src and dst
                         * fields are big enough to hold an IPv6
                         * address, but we only have IPv4 addresses
                         * and thus must clear out the remaining 124
                         * bits.
                         *
                         * XXX - should we just clear those bytes after
                         * copying the IPv4 addresses, rather than
                         * zeroing out the entire structure and then
                         * overwriting some of the zeroes?
                         *
                         * XXX - this could fail if we see TCP packets
                         * with an IPv6 address with the lower 124 bits
                         * all zero and also see TCP packes with an
                         * IPv4 address with the same 32 bits as the
                         * upper 32 bits of the IPv6 address in question.
                         * Can that happen?  Is it likely enough to be
                         * an issue?
                         */
                        memset(&tha, 0, sizeof(tha));
                        src = &ip->ip_src;
                        dst = &ip->ip_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip->ip_dst);
                                memcpy(&tha.dst, src, sizeof ip->ip_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                                memcpy(&tha.src, src, sizeof ip->ip_src);
                                tha.port = sport << 16 | dport;
                        }
                }
#else
                rev = 0;
                src = &ip->ip_src;
                dst = &ip->ip_dst;
                if (sport > dport)
                        rev = 1;
                else if (sport == dport) {
                        if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                rev = 1;
                }
                if (rev) {
                        memcpy(&tha.src, dst, sizeof ip->ip_dst);
                        memcpy(&tha.dst, src, sizeof ip->ip_src);
                        tha.port = dport << 16 | sport;
                } else {
                        memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                        memcpy(&tha.src, src, sizeof ip->ip_src);
                        tha.port = sport << 16 | dport;
                }
#endif

                threv = rev;
                for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                     th->nxt; th = th->nxt)
                        if (memcmp((char *)&tha, (char *)&th->addr,
                                   sizeof(th->addr)) == 0)
                                break;

                if (!th->nxt || (flags & TH_SYN)) {
                        /* didn't find it or new conversation */
                        if (th->nxt == NULL) {
                                th->nxt = (struct tcp_seq_hash *)
                                        calloc(1, sizeof(*th));
                                if (th->nxt == NULL)
                                        error("tcp_print: calloc");
                        }
                        th->addr = tha;
                        if (rev)
                                th->ack = seq, th->seq = ack - 1;
                        else
                                th->seq = seq, th->ack = ack - 1;
                } else {
                        if (rev)
                                seq -= th->ack, ack -= th->seq;
                        else
                                seq -= th->seq, ack -= th->ack;
                }

                thseq = th->seq;
                thack = th->ack;
        } else {
                /*fool gcc*/
                thseq = thack = threv = 0;
        }
        if (hlen > length) {
                (void)printf(" [bad hdr length %u - too long, > %u]",
                             hlen, length);
                return;
        }

        if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) {
                u_int16_t sum, tcp_sum;
                if (TTEST2(tp->th_sport, length)) {
                        sum = tcp_cksum(ip, tp, length);

                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                        if (sum != 0) {
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);
                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
                        } else
                                (void)printf(" (correct)");
                }
        }
#ifdef INET6
        if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
                u_int16_t sum,tcp_sum;
                if (TTEST2(tp->th_sport, length)) {
                        sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                        if (sum != 0) {
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);
                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
                        } else
                                (void)printf(" (correct)");

                }
        }
#endif

        length -= hlen;
        if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
                (void)printf(", seq %u", seq);

                if (length > 0) {
                        (void)printf(":%u", seq + length);
                }
        }

        if (flags & TH_ACK) {
                (void)printf(", ack %u", ack);
        }

        (void)printf(", win %d", win);

        if (flags & TH_URG)
                (void)printf(", urg %d", urp);
        /*
         * Handle any options.
         */
        if (hlen > sizeof(*tp)) {
                register const u_char *cp;
                register u_int i, opt, datalen;
                register u_int len;

                hlen -= sizeof(*tp);
                cp = (const u_char *)tp + sizeof(*tp);
                printf(", options [");
                while (hlen > 0) {
                        if (ch != '\0')
                                putchar(ch);
                        TCHECK(*cp);
                        opt = *cp++;
                        if (ZEROLENOPT(opt))
                                len = 1;
                        else {
                                TCHECK(*cp);
                                len = *cp++;	/* total including type, len */
                                if (len < 2 || len > hlen)
                                        goto bad;
                                --hlen;		/* account for length byte */
                        }
                        --hlen;			/* account for type byte */
                        datalen = 0;

/* Bail if "l" bytes of data are not left or were not captured  */
#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }


                        printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));

                        switch (opt) {

                        case TCPOPT_MAXSEG:
                                datalen = 2;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_16BITS(cp));
                                break;

                        case TCPOPT_WSCALE:
                                datalen = 1;
                                LENCHECK(datalen);
                                (void)printf(" %u", *cp);
                                break;

                        case TCPOPT_SACK:
                                datalen = len - 2;
                                if (datalen % 8 != 0) {
                                        (void)printf("malformed sack");
                                } else {
                                        u_int32_t s, e;

                                        (void)printf(" %d ", datalen / 8);
                                        for (i = 0; i < datalen; i += 8) {
                                                LENCHECK(i + 4);
                                                s = EXTRACT_32BITS(cp + i);
                                                LENCHECK(i + 8);
                                                e = EXTRACT_32BITS(cp + i + 4);
                                                if (threv) {
                                                        s -= thseq;
                                                        e -= thseq;
                                                } else {
                                                        s -= thack;
                                                        e -= thack;
                                                }
                                                (void)printf("{%u:%u}", s, e);
                                        }
                                }
                                break;

                        case TCPOPT_CC:
                        case TCPOPT_CCNEW:
                        case TCPOPT_CCECHO:
                        case TCPOPT_ECHO:
                        case TCPOPT_ECHOREPLY:

                                /*
                                 * those options share their semantics.
                                 * fall through
                                 */
                                datalen = 4;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_32BITS(cp));
                                break;

                        case TCPOPT_TIMESTAMP:
                                datalen = 8;
                                LENCHECK(datalen);
                                (void)printf(" val %u ecr %u",
                                             EXTRACT_32BITS(cp),
                                             EXTRACT_32BITS(cp + 4));
                                break;

                        case TCPOPT_SIGNATURE:
                                datalen = TCP_SIGLEN;
                                LENCHECK(datalen);
#ifdef HAVE_LIBCRYPTO
                                switch (tcp_verify_signature(ip, tp,
                                                             bp + TH_OFF(tp) * 4, length, cp)) {

                                case SIGNATURE_VALID:
                                        (void)printf("valid");
                                        break;

                                case SIGNATURE_INVALID:
                                        (void)printf("invalid");
                                        break;

                                case CANT_CHECK_SIGNATURE:
                                        (void)printf("can't check - ");
                                        for (i = 0; i < TCP_SIGLEN; ++i)
                                                (void)printf("%02x", cp[i]);
                                        break;
                                }
#else
                                for (i = 0; i < TCP_SIGLEN; ++i)
                                        (void)printf("%02x", cp[i]);
#endif
                                break;

                        case TCPOPT_AUTH:
                                (void)printf("keyid %d", *cp++);
                                datalen = len - 3;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;


                        case TCPOPT_EOL:
                        case TCPOPT_NOP:
                        case TCPOPT_SACKOK:
                                /*
                                 * Nothing interesting.
                                 * fall through
                                 */
                                break;

                        case TCPOPT_UTO:
                                datalen = 2;
                                LENCHECK(datalen);
                                utoval = EXTRACT_16BITS(cp);
                                (void)printf("0x%x", utoval);
                                if (utoval & 0x0001)
                                        utoval = (utoval >> 1) * 60;
                                else
                                        utoval >>= 1;
                                (void)printf(" %u", utoval);
                                break;

                        default:
                                datalen = len - 2;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;
                        }

                        /* Account for data printed */
                        cp += datalen;
                        hlen -= datalen;

                        /* Check specification against observed length */
                        ++datalen;			/* option octet */
                        if (!ZEROLENOPT(opt))
                                ++datalen;		/* size octet */
                        if (datalen != len)
                                (void)printf("[len %d]", len);
                        ch = ',';
                        if (opt == TCPOPT_EOL)
                                break;
                }
                putchar(']');
        }
Beispiel #8
0
void
tcp_print(const u_char *bp, u_int length, const u_char *bp2)
{
	const struct tcphdr *tp;
	const struct ip *ip;
	u_char flags;
	int hlen;
	char ch;
	struct tcp_seq_hash *th = NULL;
	int rev = 0;
	u_int16_t sport, dport, win, urp;
	tcp_seq seq, ack;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif

	tp = (struct tcphdr *)bp;
	switch (((struct ip *)bp2)->ip_v) {
	case 4:
		ip = (struct ip *)bp2;
#ifdef INET6
		ip6 = NULL;
#endif
		break;
#ifdef INET6
	case 6:
		ip = NULL;
		ip6 = (struct ip6_hdr *)bp2;
		break;
#endif
	default:
		(void)printf("invalid ip version");
		return;
	}

	ch = '\0';
	if (length < sizeof(*tp)) {
		(void)printf("truncated-tcp %u", length);
		return;
	}

	if (!TTEST(tp->th_dport)) {
#ifdef INET6
		if (ip6) {
			(void)printf("%s > %s: [|tcp]",
				ip6addr_string(&ip6->ip6_src),
				ip6addr_string(&ip6->ip6_dst));
		} else
#endif /*INET6*/
		{
			(void)printf("%s > %s: [|tcp]",
				ipaddr_string(&ip->ip_src),
				ipaddr_string(&ip->ip_dst));
		}
		return;
	}

	sport = ntohs(tp->th_sport);
	dport = ntohs(tp->th_dport);

#ifdef INET6
	if (ip6) {
		if (ip6->ip6_nxt == IPPROTO_TCP) {
			(void)printf("%s.%s > %s.%s: ",
				ip6addr_string(&ip6->ip6_src),
				tcpport_string(sport),
				ip6addr_string(&ip6->ip6_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	} else
#endif /*INET6*/
	{
		if (ip->ip_p == IPPROTO_TCP) {
			(void)printf("%s.%s > %s.%s: ",
				ipaddr_string(&ip->ip_src),
				tcpport_string(sport),
				ipaddr_string(&ip->ip_dst),
				tcpport_string(dport));
		} else {
			(void)printf("%s > %s: ",
				tcpport_string(sport), tcpport_string(dport));
		}
	}

	if (!qflag && TTEST(tp->th_seq) && !TTEST(tp->th_ack))
		(void)printf("%u ", ntohl(tp->th_seq));

	TCHECK(*tp);
	seq = ntohl(tp->th_seq);
	ack = ntohl(tp->th_ack);
	win = ntohs(tp->th_win);
	urp = ntohs(tp->th_urp);
	hlen = tp->th_off * 4;

	if (qflag) {
		(void)printf("tcp %d", length - tp->th_off * 4);
		return;
	} else if (packettype != PT_TCP) {

		/*
		 * If data present and NFS port used, assume NFS.
		 * Pass offset of data plus 4 bytes for RPC TCP msg length
		 * to NFS print routines.
		 */
		u_int len = length - hlen;
		if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
		    dport == NFS_PORT) {
			nfsreq_print((u_char *)tp + hlen + 4, len, bp2);
			return;
		} else if ((u_char *)tp + 4 + 
		    sizeof(struct rpc_msg) <= snapend && sport == NFS_PORT) {
			nfsreply_print((u_char *)tp + hlen + 4, len, bp2);
			return;
		}
	}
	if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
				      TH_ECNECHO|TH_CWR)) {
		if (flags & TH_SYN)
			putchar('S');
		if (flags & TH_FIN)
			putchar('F');
		if (flags & TH_RST)
			putchar('R');
		if (flags & TH_PUSH)
			putchar('P');
		if (flags & TH_CWR)
			putchar('W');	/* congestion _W_indow reduced (ECN) */
		if (flags & TH_ECNECHO)
			putchar('E');	/* ecn _E_cho sent (ECN) */
	} else
		putchar('.');

	if (!Sflag && (flags & TH_ACK)) {
		struct tha tha;
		/*
		 * Find (or record) the initial sequence numbers for
		 * this conversation.  (we pick an arbitrary
		 * collating order so there's only one entry for
		 * both directions).
		 */
#ifdef INET6
		bzero(&tha, sizeof(tha));
		rev = 0;
		if (ip6) {
			if (sport > dport) {
				rev = 1;
			} else if (sport == dport) {
			    int i;

			    for (i = 0; i < 4; i++) {
				if (((u_int32_t *)(&ip6->ip6_src))[i] >
				    ((u_int32_t *)(&ip6->ip6_dst))[i]) {
					rev = 1;
					break;
				}
			    }
			}
			if (rev) {
				tha.src = ip6->ip6_dst;
				tha.dst = ip6->ip6_src;
				tha.port = dport << 16 | sport;
			} else {
				tha.dst = ip6->ip6_dst;
				tha.src = ip6->ip6_src;
				tha.port = sport << 16 | dport;
			}
		} else {
			if (sport > dport ||
			    (sport == dport &&
			     ip->ip_src.s_addr > ip->ip_dst.s_addr)) {
				rev = 1;
			}
			if (rev) {
				*(struct in_addr *)&tha.src = ip->ip_dst;
				*(struct in_addr *)&tha.dst = ip->ip_src;
				tha.port = dport << 16 | sport;
			} else {
				*(struct in_addr *)&tha.dst = ip->ip_dst;
				*(struct in_addr *)&tha.src = ip->ip_src;
				tha.port = sport << 16 | dport;
			}
		}
#else
		if (sport < dport ||
		    (sport == dport &&
		     ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
			tha.src = ip->ip_src, tha.dst = ip->ip_dst;
			tha.port = sport << 16 | dport;
			rev = 0;
		} else {
			tha.src = ip->ip_dst, tha.dst = ip->ip_src;
			tha.port = dport << 16 | sport;
			rev = 1;
		}
#endif

		for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
		     th->nxt; th = th->nxt)
			if (!memcmp((char *)&tha, (char *)&th->addr,
				  sizeof(th->addr)))
				break;

		if (!th->nxt || flags & TH_SYN) {
			/* didn't find it or new conversation */
			if (th->nxt == NULL) {
				th->nxt = calloc(1, sizeof(*th));
				if (th->nxt == NULL)
					error("tcp_print: calloc");
			}
			th->addr = tha;
			if (rev)
				th->ack = seq, th->seq = ack - 1;
			else
				th->seq = seq, th->ack = ack - 1;
		} else {
			if (rev)
				seq -= th->ack, ack -= th->seq;
			else
				seq -= th->seq, ack -= th->ack;
		}
	}
	hlen = tp->th_off * 4;
	if (hlen > length) {
		(void)printf(" [bad hdr length]");
		return;
	}

	if (ip && ip->ip_v == 4 && vflag) {
		if (TTEST2(tp->th_sport, length)) {
			u_int16_t sum, tcp_sum;
			sum = tcp_cksum(ip, tp, length);
			if (sum != 0) {
				tcp_sum = EXTRACT_16BITS(&tp->th_sum);
				(void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum,
				    in_cksum_shouldbe(tcp_sum, sum));
			} else
				(void)printf(" [tcp sum ok]");
		}
	}
#ifdef INET6
	if (ip6 && ip6->ip6_plen && vflag) {
		if (TTEST2(tp->th_sport, length)) {
			u_int16_t sum, tcp_sum;
			sum = tcp6_cksum(ip6, tp, length);
			if (sum != 0) {
				tcp_sum = EXTRACT_16BITS(&tp->th_sum);
				(void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum,
				    in_cksum_shouldbe(tcp_sum, sum));
			} else
				(void)printf(" [tcp sum ok]");
		}
	}
#endif

	/* OS Fingerprint */
	if (oflag && (flags & (TH_SYN|TH_ACK)) == TH_SYN) {
		struct pf_osfp_enlist *head = NULL;
		struct pf_osfp_entry *fp;
		unsigned long left;
		left = (unsigned long)(snapend - (const u_char *)tp);

		if (left >= hlen)
			head = pf_osfp_fingerprint_hdr(ip, ip6, tp);
		if (head) {
			int prev = 0;
			printf(" (src OS:");
			SLIST_FOREACH(fp, head, fp_entry) {
				if (fp->fp_enflags & PF_OSFP_EXPANDED)
					continue;
				if (prev)
					printf(",");
				printf(" %s", fp->fp_class_nm);
				if (fp->fp_version_nm[0])
					printf(" %s", fp->fp_version_nm);
				if (fp->fp_subtype_nm[0])
					printf(" %s", fp->fp_subtype_nm);
				prev = 1;
			}
			printf(")");
		} else {
			if (left < hlen)
				printf(" (src OS: short-pkt)");
			else
				printf(" (src OS: unknown)");
		}
	}
Beispiel #9
0
void
icmp_print(const u_char *bp, u_int length, const u_char *bp2)
{
	const struct icmp *dp;
	const struct ip *ip;
	const char *str, *fmt;
	const struct ip *oip;
	const struct udphdr *ouh;
	u_int hlen, dport, mtu;
	char buf[MAXHOSTNAMELEN+256];
	char buf2[MAXHOSTNAMELEN+256];

	dp = (struct icmp *)bp;
	ip = (struct ip *)bp2;
	str = buf;

        (void)printf("%s > %s: ",
		ipaddr_string(&ip->ip_src),
		ipaddr_string(&ip->ip_dst));

	TCHECK(dp->icmp_code);
	if (qflag) 
		(void) snprintf(buf, sizeof buf, "%u %u", dp->icmp_type,
		    dp->icmp_code);
	else switch (dp->icmp_type) {

	case ICMP_ECHOREPLY:
	case ICMP_ECHO:
		if (vflag) {
			TCHECK(dp->icmp_seq);
			(void)snprintf(buf, sizeof buf,
				       "echo %s (id:%04x seq:%u)",
				       (dp->icmp_type == ICMP_ECHO)?
				       "request": "reply",
				       ntohs(dp->icmp_id),
				       ntohs(dp->icmp_seq));
		} else
			str = tok2str(icmp2str, "type-#%u", dp->icmp_type);
		break;

	case ICMP_UNREACH:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_UNREACH_PROTOCOL:
			TCHECK(dp->icmp_ip.ip_p);
			(void)snprintf(buf, sizeof buf,
				       "%s protocol %u unreachable",
				       ipaddr_string(&dp->icmp_ip.ip_dst),
				       dp->icmp_ip.ip_p);
			break;

		case ICMP_UNREACH_PORT:
			TCHECK(dp->icmp_ip.ip_p);
			oip = &dp->icmp_ip;
			hlen = oip->ip_hl * 4;
			ouh = (struct udphdr *)(((u_char *)oip) + hlen);
			TCHECK(ouh->uh_dport);
			dport = ntohs(ouh->uh_dport);
			switch (oip->ip_p) {

			case IPPROTO_TCP:
				(void)snprintf(buf, sizeof buf,
					"%s tcp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					tcpport_string(dport));
				break;

			case IPPROTO_UDP:
				(void)snprintf(buf, sizeof buf,
					"%s udp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					udpport_string(dport));
				break;

			default:
				(void)snprintf(buf, sizeof buf,
					"%s protocol %u port %u unreachable",
					ipaddr_string(&oip->ip_dst),
					oip->ip_p, dport);
				break;
			}
			break;

		case ICMP_UNREACH_NEEDFRAG:
			{
			const struct mtu_discovery *mp;

			mp = (struct mtu_discovery *)&dp->icmp_void;
                        mtu = EXTRACT_16BITS(&mp->nexthopmtu);
                        if (mtu)
			    (void)snprintf(buf, sizeof buf,
				"%s unreachable - need to frag (mtu %u)",
				ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
                        else
			    (void)snprintf(buf, sizeof buf,
				"%s unreachable - need to frag",
				ipaddr_string(&dp->icmp_ip.ip_dst));
			}
			break;

		default:
			fmt = tok2str(unreach2str, "#%u %%s unreachable",
			    dp->icmp_code);
			(void)snprintf(buf, sizeof buf, fmt,
			    ipaddr_string(&dp->icmp_ip.ip_dst));
			break;
		}
		break;

	case ICMP_REDIRECT:
		TCHECK(dp->icmp_ip.ip_dst);
		fmt = tok2str(type2str, "redirect-#%u %%s to net %%s",
		    dp->icmp_code);
		(void)snprintf(buf, sizeof buf, fmt,
		    ipaddr_string(&dp->icmp_ip.ip_dst),
		    ipaddr_string(&dp->icmp_gwaddr));
		break;

	case ICMP_ROUTERADVERT:
		{
		const struct ih_rdiscovery *ihp;
		const struct id_rdiscovery *idp;
		u_int lifetime, num, size;

		(void)strlcpy(buf, "router advertisement", sizeof(buf));

		ihp = (struct ih_rdiscovery *)&dp->icmp_void;
		TCHECK(*ihp);
		(void)strlcat(buf, " lifetime ", sizeof(buf));
		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
		if (lifetime < 60)
			(void)snprintf(buf2, sizeof(buf2), "%u", lifetime);
		else if (lifetime < 60 * 60)
			(void)snprintf(buf2, sizeof(buf2), "%u:%02u",
			    lifetime / 60, lifetime % 60);
		else
			(void)snprintf(buf2, sizeof(buf2), "%u:%02u:%02u",
			    lifetime / 3600, (lifetime % 3600) / 60,
			    lifetime % 60);
		strlcat(buf, buf2, sizeof(buf));

		num = ihp->ird_addrnum;
		(void)snprintf(buf2, sizeof(buf2), " %u:", num);
		strlcat(buf, buf2, sizeof(buf));

		size = ihp->ird_addrsiz;
		if (size != 2) {
			(void)snprintf(buf2, sizeof(buf2), " [size %u]", size);
			strlcat(buf, buf2, sizeof(buf));
			break;
		}
		idp = (struct id_rdiscovery *)&dp->icmp_data;
		while (num-- > 0) {
			TCHECK(*idp);
			(void)snprintf(buf2, sizeof(buf2), " {%s %u}",
			    ipaddr_string(&idp->ird_addr),
			    EXTRACT_32BITS(&idp->ird_pref));
			strlcat(buf, buf2, sizeof(buf));
		}
		}
		break;

	case ICMP_TIMXCEED:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_TIMXCEED_INTRANS:
			str = "time exceeded in-transit";
			break;

		case ICMP_TIMXCEED_REASS:
			str = "ip reassembly time exceeded";
			break;

		default:
			(void)snprintf(buf, sizeof buf,
				"time exceeded-#%u", dp->icmp_code);
			break;
		}
		break;

	case ICMP_PARAMPROB:
		switch (dp->icmp_code) {
		case ICMP_PARAMPROB_OPTABSENT:
			str = "requested option absent";
			break;
		case ICMP_PARAMPROB_LENGTH:
			snprintf(buf, sizeof buf, "bad length %u", dp->icmp_pptr);
			break;
		default:
			TCHECK(dp->icmp_pptr);
			(void)snprintf(buf, sizeof buf,
				"parameter problem - octet %u",
				dp->icmp_pptr);
			break;
		}
		break;

	case ICMP_MASKREPLY:
		TCHECK(dp->icmp_mask);
		(void)snprintf(buf, sizeof buf, "address mask is 0x%08x",
		    (u_int32_t)ntohl(dp->icmp_mask));
		break;

	default:
		str = tok2str(icmp2str, "type-#%u", dp->icmp_type);
		break;
	}
	(void)printf("icmp: %s", str);
	if (vflag) {
		u_int16_t sum;
		if (TTEST2(dp->icmp_type, length)) {
			sum = in_cksum((const u_short *)dp, length, 0);
			if (sum != 0)
				(void)printf(" [bad icmp cksum %x!]", sum);
			else
				(void)printf(" [icmp cksum ok]");
		}
    }
	if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type) &&
	    TTEST(dp->icmp_ip)) {
		(void)printf(" for ");
		oip = &dp->icmp_ip;
		ip_print((u_char *)oip, ntohs(oip->ip_len));
	}
	return;
trunc:
	fputs("[|icmp]", stdout);
}
Beispiel #10
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2, int fragmented)
{
        register const struct tcphdr *tp;
        register const struct ip *ip;
        register u_char flags;
        register u_int hlen;
        register char ch;
        u_int16_t sport, dport, win, urp;
        u_int32_t seq, ack, thseq, thack;
        u_int utoval;
        u_int16_t magic;
        register int rev;
#ifdef INET6
        register const struct ip6_hdr *ip6;
#endif

        tp = (struct tcphdr *)bp;
        ip = (struct ip *)bp2;
#ifdef INET6
        if (IP_V(ip) == 6)
                ip6 = (struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
#endif /*INET6*/
        ch = '\0';
        if (!TTEST(tp->th_dport)) {
                (void)printf("%s > %s: [|tcp]",
                             ipaddr_string(&ip->ip_src),
                             ipaddr_string(&ip->ip_dst));
                return;
        }

        sport = EXTRACT_16BITS(&tp->th_sport);
        dport = EXTRACT_16BITS(&tp->th_dport);

        hlen = TH_OFF(tp) * 4;

#ifdef INET6
        if (ip6) {
                if (ip6->ip6_nxt == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ip6addr_string(&ip6->ip6_src),
                                     tcpport_string(sport),
                                     ip6addr_string(&ip6->ip6_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        } else
#endif /*INET6*/
        {
                if (ip->ip_p == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ipaddr_string(&ip->ip_src),
                                     tcpport_string(sport),
                                     ipaddr_string(&ip->ip_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        }

        if (hlen < sizeof(*tp)) {
                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        TCHECK(*tp);

        seq = EXTRACT_32BITS(&tp->th_seq);
        ack = EXTRACT_32BITS(&tp->th_ack);
        win = EXTRACT_16BITS(&tp->th_win);
        urp = EXTRACT_16BITS(&tp->th_urp);

        if (qflag) {
                (void)printf("tcp %d", length - hlen);
                if (hlen > length) {
                        (void)printf(" [bad hdr length %u - too long, > %u]",
                                     hlen, length);
                }
                return;
        }

        flags = tp->th_flags;
        printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!Sflag && (flags & TH_ACK)) {
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
                rev = 0;
#ifdef INET6
                if (ip6) {
                        register struct tcp_seq_hash6 *th;
                        struct tcp_seq_hash6 *tcp_seq_hash;
                        const struct in6_addr *src, *dst;
                        struct tha6 tha;

                        tcp_seq_hash = tcp_seq_hash6;
                        src = &ip6->ip6_src;
                        dst = &ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
                                tha.port = sport << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash6 *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                error("tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                } else {
#else  /*INET6*/
                {
#endif /*INET6*/
                        register struct tcp_seq_hash *th;
                        struct tcp_seq_hash *tcp_seq_hash;
                        const struct in_addr *src, *dst;
                        struct tha tha;

                        tcp_seq_hash = tcp_seq_hash4;
                        src = &ip->ip_src;
                        dst = &ip->ip_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip->ip_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip->ip_dst);
                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip->ip_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst);
                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip->ip_src);
                                tha.port = sport << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                error("tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                }
        } else {
Beispiel #11
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2, int fragmented)
{
        register const struct tcphdr *tp;
        register const struct ip *ip;
        register u_char flags;
        register u_int hlen;
        register char ch;
        u_int16_t sport, dport, win, urp;
        u_int32_t seq, ack, thseq, thack;
        u_int utoval;
        int threv;
#ifdef INET6
        register const struct ip6_hdr *ip6;
#endif

        tp = (struct tcphdr *)bp;
        ip = (struct ip *)bp2;
#ifdef INET6
        if (IP_V(ip) == 6)
                ip6 = (struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
#endif /*INET6*/
        ch = '\0';
        if (!TTEST(tp->th_dport)) {
                (void)printf("%s > %s: [|tcp]",
                             ipaddr_string(&ip->ip_src),
                             ipaddr_string(&ip->ip_dst));
                return;
        }

        sport = EXTRACT_16BITS(&tp->th_sport);
        dport = EXTRACT_16BITS(&tp->th_dport);

        hlen = TH_OFF(tp) * 4;

        /*
	 * If data present, header length valid, and NFS port used,
	 * assume NFS.
	 * Pass offset of data plus 4 bytes for RPC TCP msg length
	 * to NFS print routines.
	 */
	if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
	    (length - hlen) >= 4) {
		u_char *fraglenp;
		u_int32_t fraglen;
		register struct sunrpc_msg *rp;
		enum sunrpc_msg_type direction;

		fraglenp = (u_char *)tp + hlen;
		if (TTEST2(*fraglenp, 4)) {
			fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
			if (fraglen > (length - hlen) - 4)
				fraglen = (length - hlen) - 4;
			rp = (struct sunrpc_msg *)(fraglenp + 4);
			if (TTEST(rp->rm_direction)) {
				direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
				if (dport == NFS_PORT &&
				    direction == SUNRPC_CALL) {
					nfsreq_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
				if (sport == NFS_PORT &&
				    direction == SUNRPC_REPLY) {
					nfsreply_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
			}
                }
        }
#ifdef INET6
        if (ip6) {
                if (ip6->ip6_nxt == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ip6addr_string(&ip6->ip6_src),
                                     tcpport_string(sport),
                                     ip6addr_string(&ip6->ip6_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        } else
#endif /*INET6*/
        {
                if (ip->ip_p == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ipaddr_string(&ip->ip_src),
                                     tcpport_string(sport),
                                     ipaddr_string(&ip->ip_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        }

        if (hlen < sizeof(*tp)) {
                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        TCHECK(*tp);

        seq = EXTRACT_32BITS(&tp->th_seq);
        ack = EXTRACT_32BITS(&tp->th_ack);
        win = EXTRACT_16BITS(&tp->th_win);
        urp = EXTRACT_16BITS(&tp->th_urp);

        if (qflag) {
                (void)printf("tcp %d", length - hlen);
                if (hlen > length) {
                        (void)printf(" [bad hdr length %u - too long, > %u]",
                                     hlen, length);
                }
                return;
        }

        flags = tp->th_flags;
        printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!Sflag && (flags & TH_ACK)) {
                register struct tcp_seq_hash *th;
                const void *src, *dst;
                register int rev;
                struct tha tha;
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
#ifdef INET6
                rev = 0;
                if (ip6) {
                        src = &ip6->ip6_src;
                        dst = &ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.dst, src, sizeof ip6->ip6_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.src, src, sizeof ip6->ip6_src);
                                tha.port = sport << 16 | dport;
                        }
                } else {
                        /*
                         * Zero out the tha structure; the src and dst
                         * fields are big enough to hold an IPv6
                         * address, but we only have IPv4 addresses
                         * and thus must clear out the remaining 124
                         * bits.
                         *
                         * XXX - should we just clear those bytes after
                         * copying the IPv4 addresses, rather than
                         * zeroing out the entire structure and then
                         * overwriting some of the zeroes?
                         *
                         * XXX - this could fail if we see TCP packets
                         * with an IPv6 address with the lower 124 bits
                         * all zero and also see TCP packes with an
                         * IPv4 address with the same 32 bits as the
                         * upper 32 bits of the IPv6 address in question.
                         * Can that happen?  Is it likely enough to be
                         * an issue?
                         */
                        memset(&tha, 0, sizeof(tha));
                        src = &ip->ip_src;
                        dst = &ip->ip_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip->ip_dst);
                                memcpy(&tha.dst, src, sizeof ip->ip_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                                memcpy(&tha.src, src, sizeof ip->ip_src);
                                tha.port = sport << 16 | dport;
                        }
                }
#else
                rev = 0;
                src = &ip->ip_src;
                dst = &ip->ip_dst;
                if (sport > dport)
                        rev = 1;
                else if (sport == dport) {
                        if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                rev = 1;
                }
                if (rev) {
                        memcpy(&tha.src, dst, sizeof ip->ip_dst);
                        memcpy(&tha.dst, src, sizeof ip->ip_src);
                        tha.port = dport << 16 | sport;
                } else {
                        memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                        memcpy(&tha.src, src, sizeof ip->ip_src);
                        tha.port = sport << 16 | dport;
                }
#endif

                threv = rev;
                for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                     th->nxt; th = th->nxt)
                        if (memcmp((char *)&tha, (char *)&th->addr,
                                   sizeof(th->addr)) == 0)
                                break;

                if (!th->nxt || (flags & TH_SYN)) {
                        /* didn't find it or new conversation */
                        if (th->nxt == NULL) {
                                th->nxt = (struct tcp_seq_hash *)
                                        calloc(1, sizeof(*th));
                                if (th->nxt == NULL)
                                        error("tcp_print: calloc");
                        }
                        th->addr = tha;
                        if (rev)
                                th->ack = seq, th->seq = ack - 1;
                        else
                                th->seq = seq, th->ack = ack - 1;
                } else {
                        if (rev)
                                seq -= th->ack, ack -= th->seq;
                        else
                                seq -= th->seq, ack -= th->ack;
                }

                thseq = th->seq;
                thack = th->ack;
        } else {
                /*fool gcc*/
                thseq = thack = threv = 0;
        }
        if (hlen > length) {
                (void)printf(" [bad hdr length %u - too long, > %u]",
                             hlen, length);
                return;
        }

        if (vflag && !Kflag && !fragmented) {
                /* Check the checksum, if possible. */
                u_int16_t sum, tcp_sum;

                if (IP_V(ip) == 4) {
                        if (TTEST2(tp->th_sport, length)) {
                                sum = tcp_cksum(ip, tp, length);
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);

                                (void)printf(", cksum 0x%04x", tcp_sum);
                                if (sum != 0)
                                        (void)printf(" (incorrect -> 0x%04x)",
                                            in_cksum_shouldbe(tcp_sum, sum));
                                else
                                        (void)printf(" (correct)");
                        }
                }
#ifdef INET6
                else if (IP_V(ip) == 6 && ip6->ip6_plen) {
                        if (TTEST2(tp->th_sport, length)) {
                                sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP);
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);

                                (void)printf(", cksum 0x%04x", tcp_sum);
                                if (sum != 0)
                                        (void)printf(" (incorrect -> 0x%04x)",
                                            in_cksum_shouldbe(tcp_sum, sum));
                                else
                                        (void)printf(" (correct)");

                        }
                }
#endif
        }

        length -= hlen;
        if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
                (void)printf(", seq %u", seq);

                if (length > 0) {
                        (void)printf(":%u", seq + length);
                }
        }

        if (flags & TH_ACK) {
                (void)printf(", ack %u", ack);
        }

        (void)printf(", win %d", win);

        if (flags & TH_URG)
                (void)printf(", urg %d", urp);
        /*
         * Handle any options.
         */
        if (hlen > sizeof(*tp)) {
                register const u_char *cp;
                register u_int i, opt, datalen;
                register u_int len;

                hlen -= sizeof(*tp);
                cp = (const u_char *)tp + sizeof(*tp);
                printf(", options [");
                while (hlen > 0) {
                        if (ch != '\0')
                                putchar(ch);
                        TCHECK(*cp);
                        opt = *cp++;
                        if (ZEROLENOPT(opt))
                                len = 1;
                        else {
                                TCHECK(*cp);
                                len = *cp++;	/* total including type, len */
                                if (len < 2 || len > hlen)
                                        goto bad;
                                --hlen;		/* account for length byte */
                        }
                        --hlen;			/* account for type byte */
                        datalen = 0;

/* Bail if "l" bytes of data are not left or were not captured  */
#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }


                        printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));

                        switch (opt) {

                        case TCPOPT_MAXSEG:
                                datalen = 2;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_16BITS(cp));
                                break;

                        case TCPOPT_WSCALE:
                                datalen = 1;
                                LENCHECK(datalen);
                                (void)printf(" %u", *cp);
                                break;

                        case TCPOPT_SACK:
                                datalen = len - 2;
                                if (datalen % 8 != 0) {
                                        (void)printf("malformed sack");
                                } else {
                                        u_int32_t s, e;

                                        (void)printf(" %d ", datalen / 8);
                                        for (i = 0; i < datalen; i += 8) {
                                                LENCHECK(i + 4);
                                                s = EXTRACT_32BITS(cp + i);
                                                LENCHECK(i + 8);
                                                e = EXTRACT_32BITS(cp + i + 4);
                                                if (threv) {
                                                        s -= thseq;
                                                        e -= thseq;
                                                } else {
                                                        s -= thack;
                                                        e -= thack;
                                                }
                                                (void)printf("{%u:%u}", s, e);
                                        }
                                }
                                break;

                        case TCPOPT_CC:
                        case TCPOPT_CCNEW:
                        case TCPOPT_CCECHO:
                        case TCPOPT_ECHO:
                        case TCPOPT_ECHOREPLY:

                                /*
                                 * those options share their semantics.
                                 * fall through
                                 */
                                datalen = 4;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_32BITS(cp));
                                break;

                        case TCPOPT_TIMESTAMP:
                                datalen = 8;
                                LENCHECK(datalen);
                                (void)printf(" val %u ecr %u",
                                             EXTRACT_32BITS(cp),
                                             EXTRACT_32BITS(cp + 4));
                                break;

                        case TCPOPT_SIGNATURE:
                                datalen = TCP_SIGLEN;
                                LENCHECK(datalen);
#ifdef HAVE_LIBCRYPTO
                                switch (tcp_verify_signature(ip, tp,
                                                             bp + TH_OFF(tp) * 4, length, cp)) {

                                case SIGNATURE_VALID:
                                        (void)printf("valid");
                                        break;

                                case SIGNATURE_INVALID:
                                        (void)printf("invalid");
                                        break;

                                case CANT_CHECK_SIGNATURE:
                                        (void)printf("can't check - ");
                                        for (i = 0; i < TCP_SIGLEN; ++i)
                                                (void)printf("%02x", cp[i]);
                                        break;
                                }
#else
                                for (i = 0; i < TCP_SIGLEN; ++i)
                                        (void)printf("%02x", cp[i]);
#endif
                                break;

                        case TCPOPT_AUTH:
                                (void)printf("keyid %d", *cp++);
                                datalen = len - 3;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;


                        case TCPOPT_EOL:
                        case TCPOPT_NOP:
                        case TCPOPT_SACKOK:
                                /*
                                 * Nothing interesting.
                                 * fall through
                                 */
                                break;

                        case TCPOPT_UTO:
                                datalen = 2;
                                LENCHECK(datalen);
                                utoval = EXTRACT_16BITS(cp);
                                (void)printf("0x%x", utoval);
                                if (utoval & 0x0001)
                                        utoval = (utoval >> 1) * 60;
                                else
                                        utoval >>= 1;
                                (void)printf(" %u", utoval);
                                break;

			case TCPOPT_MPTCP: {
				uint8_t subtype;
				
				datalen = 1;
				LENCHECK(datalen);
				
				subtype = (*cp) >> 4;
				
				printf(" %s ", tok2str(mptcp_subtypes, "Unknown MPTCP subtype %u", subtype));
				
				switch (subtype) {
					case TCPOPT_MPTCP_MP_CAPABLE: {
						uint8_t version = (*cp) & 0x0f;
						uint8_t mpflags;
						
						if (version != 0) {
							printf(" version %u ", version);
							for (i = 0; i < datalen; ++i) {
								LENCHECK(i);
								(void)printf("%02x", cp[i]);
							}
							break;
						}
						
						datalen += 1;
						LENCHECK(datalen);
						mpflags = cp[1];
						printf("%s%s%s%s%s%s%s%s%s",
						       (mpflags) ? "flags:" : "",
						       (mpflags & 0x80) ? "A" : "",
						       (mpflags & 0x40) ? "B" : "",
						       (mpflags & 0x20) ? "C" : "",
						       (mpflags & 0x10) ? "D" : "",
						       (mpflags & 0x08) ? "E" : "",
						       (mpflags & 0x04) ? "F" : "",
						       (mpflags & 0x02) ? "G" : "",
						       (mpflags & 0x01) ? "H" : "");
						
						if (len == 12 || len == 20) {
							printf(" sndkey:");
							for (i = 0; i < 8; ++i) {
								datalen++;
								LENCHECK(datalen);
								(void)printf("%02x", cp[2 + i]);
							}
							
							if (len == 20) {
								printf(" rcvkey:");
								for (i = 0; i < 8; ++i) {
									datalen++;
									LENCHECK(datalen);
									(void)printf("%02x", cp[10 + i]);
								}
							}
						} else {
							printf(" unknown:");
							datalen = len - 2;
							for (i = 0; i < datalen; ++i) {
								LENCHECK(i);
								(void)printf("%02x", cp[i]);
							}
						}
						
						break;
					}
					case TCPOPT_MPTCP_MP_JOIN: {
						uint8_t mpflags = (*cp) & 0x0f;
						
						/* Flags on SYN only */
						if (flags & TH_SYN) {
							printf("%s%s%s%s%s",
							       (mpflags) ? "flags:" : "",
							       (mpflags & 0x08) ? "0" : "",
							       (mpflags & 0x04) ? "1" : "",
							       (mpflags & 0x02) ? "2" : "",
							       (mpflags & 0x01) ? "B" : "");
						}
						/* Address ID on SYN only, otherwise ignored */
						datalen += 1;
						LENCHECK(datalen);
						if ((flags & TH_SYN))
							printf(" addrid:%0x", cp[1]);
						
						if (flags == TH_SYN && len == 12) {
							/* Initial SYN */
							printf(" rcvtok:");
							for (i = 0; i < 4; ++i) {
								datalen++;
								LENCHECK(datalen);
								(void)printf("%02x", cp[2 + i]);
							}
							printf(" sndrand:");
							for (i = 0; i < 4; ++i) {
								datalen++;
								LENCHECK(datalen);
								(void)printf("%02x", cp[6 + i]);
							}
						} else if ((flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && len == 16) {
							/* Responding SYN/ACK */
							printf(" sndhmac:");
							for (i = 0; i < 8; ++i) {
								datalen++;
								LENCHECK(datalen);
								(void)printf("%02x", cp[2 + i]);
							}
							printf(" sndrand:");
							for (i = 0; i < 4; ++i) {
								datalen++;
								LENCHECK(datalen);
								(void)printf("%02x", cp[8 + i]);
							}
						} else if ((flags & (TH_SYN | TH_ACK)) == TH_ACK && len == 24) {
							/* Third ACK */
							printf(" sndhmac:");
							for (i = 0; i < 20; ++i) {
								datalen++;
								LENCHECK(i);
								(void)printf("%02x", cp[2 + i]);
							}
						} else {
							datalen = len - 2;
							for (i = 0; i < datalen; ++i) {
								LENCHECK(i);
								(void)printf("%02x", cp[i]);
							}
						}
						break;
					}
					case TCPOPT_MPTCP_DSS: {
						uint8_t mpflags;
						u_int ack_len = 0;
						u_int dsn_len = 0;
						u_int64_t dack;
						u_int64_t dsn;
						u_int32_t sfsn;
						u_int16_t dlen;
						u_int16_t csum;
						
						datalen += 1;
						LENCHECK(datalen);
						mpflags = cp[1] & 0x1f;
						
						printf("%s%s%s%s%s%s",
						       (mpflags) ? "flags:" : "",
						       (mpflags & 0x10) ? "F" : "",
						       (mpflags & 0x08) ? "m" : "",
						       (mpflags & 0x04) ? "M" : "",
						       (mpflags & 0x02) ? "a" : "",
						       (mpflags & 0x01) ? "A" : "");
						
						if ((mpflags & MPDSS_FLAG_A)) {
							if ((mpflags & MPDSS_FLAG_a)) {
								ack_len = 8;
								datalen += ack_len;
								LENCHECK(datalen);
								dack = EXTRACT_64BITS(cp + 2);
							} else {
								ack_len = 4;
								datalen += ack_len;
								LENCHECK(datalen);
								dack = EXTRACT_32BITS(cp + 2);
							}
							(void)printf(" dack: %" PRIu64, dack);
						}
						if ((mpflags & MPDSS_FLAG_M)) {
							if ((mpflags & MPDSS_FLAG_m)) {
								dsn_len = 8;
								datalen += dsn_len;
								LENCHECK(datalen);
								dsn = EXTRACT_64BITS(cp + 2 + ack_len);
							} else {
								dsn_len = 4;
								datalen += dsn_len;
								LENCHECK(datalen);
								dsn = EXTRACT_32BITS(cp + 2 + ack_len);
							}
							(void)printf(" dsn: %" PRIu64, dsn);
							
							datalen += 4;
							LENCHECK(datalen);
							sfsn = EXTRACT_32BITS(cp + 2 + ack_len + dsn_len);
							(void)printf(" sfsn: %" PRIu32, sfsn);
							
							datalen += 2;
							LENCHECK(datalen);
							dlen = EXTRACT_16BITS(cp + 2 + ack_len + dsn_len + 4);
							(void)printf(" dlen: %" PRIu16, dlen);
							
							/*
							 * Use the length of the option to find out if
							 * the checksum is present
							 */
							if (datalen < len - 2) {
								datalen += 2;
								LENCHECK(datalen);
								csum = EXTRACT_16BITS(cp + 2 + ack_len + dsn_len + 6);
								(void)printf(" csum: %" PRIu16, csum);
							}
						}
						break;
					}
					case TCPOPT_MPTCP_ADD_ADDR: {
						uint8_t ipvers;
						u_int addrlen = 0;
						u_int16_t port;
						
						ipvers = cp[1] & 0xf0;
						printf(" vers:%u", ipvers);
						
						datalen = 2;
						LENCHECK(datalen);
						printf(" addrid:%0x", cp[1]);
						
						switch (ipvers) {
							case 4: {
								datalen = 6;
								LENCHECK(datalen);
								ipaddr_string(cp + 2);
								break;
							}
							case 6: {
								datalen = 18;
								LENCHECK(datalen);
#ifdef INET6
								ip6addr_string(cp + 2);
#endif
								break;
							}
							default:
								goto bad;
						}
						/*
						 * Use the length of the option to find out if
						 * the port is present
						 */
						if (datalen < len - 2) {
							datalen += 2;
							LENCHECK(datalen);
							
							port = EXTRACT_16BITS(cp + 2 + addrlen);
							
							printf(" port: %u", port);
						}
						break;
					}
					case TCPOPT_MPTCP_REMOVE_ADDR:
						datalen = len - 2;
						for (i = 0; i < datalen; ++i) {
							LENCHECK(i);
							(void)printf(" %u", cp[i]);
						}
						break;
						
					case TCPOPT_MPTCP_MP_PRIO: {
						uint8_t mpflags = (*cp) & 0x0f;
						
						if (mpflags == 0x01)
							printf("flag B");
						else if (mpflags != 0) {
							printf("flag %c%c%c%c%c%c%c%c",
							       mpflags & 0x80 ? '1' : '0',
							       mpflags & 0x40 ? '1' : '0',
							       mpflags & 0x20 ? '1' : '0',
							       mpflags & 0x10 ? '1' : '0',
							       mpflags & 0x08 ? '1' : '0',
							       mpflags & 0x04 ? '1' : '0',
							       mpflags & 0x02 ? '1' : '0',
							       mpflags & 0x01 ? 'B' : '0');
						}
						
						if (len == 4) {
							datalen = 2;
							LENCHECK(datalen);
							printf("%saddrid:%u", mpflags ? " " : "", cp[1]);
						}
						break;
					}
					case TCPOPT_MPTCP_MP_FAIL:
						datalen = 10;
						LENCHECK(datalen);
						
						printf(" dsn:");
						for (i = 0; i < 8; ++i) {
							(void)printf("%02x", cp[2 + i]);
						}
						break;
						
					case TCPOPT_MPTCP_MP_FASTCLOSE:
						datalen = 10;
						LENCHECK(datalen);
						
						printf(" rcvrkey:");
						for (i = 0; i < 8; ++i) {
							(void)printf("%02x", cp[2 + i]);
						}
						break;
						
					default:
						datalen = len - 2;
						for (i = 0; i < datalen; ++i) {
							LENCHECK(i);
							(void)printf("%02x", cp[i]);
						}
						break;
				}
				break;
			}
					
                        default:
                                datalen = len - 2;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;
                        }

                        /* Account for data printed */
                        cp += datalen;
                        hlen -= datalen;

                        /* Check specification against observed length */
                        ++datalen;			/* option octet */
                        if (!ZEROLENOPT(opt))
                                ++datalen;		/* size octet */
                        if (datalen != len)
                                (void)printf("[len %d]", len);
                        ch = ',';
                        if (opt == TCPOPT_EOL)
                                break;
                }
                putchar(']');
        }
Beispiel #12
0
void fixed_size_log_tests()
{
    TBEGIN( "Fixed size log tests" );

    cl::fixed_size_log log( 35 );
    TTEST( log.size() == 0 );
    TTEST( log.empty() );

    #define SIXTEEN_CHAR_STRING "A 16 byte entry\n"
    #define EIGHT_CHAR_STRING "8 bytes\n"
    #define HUGE_CHAR_STRING "This is a long char string intended to be too long to log in the fixed size log"

    log.insert( SIXTEEN_CHAR_STRING );
    TTEST( log.size() == 1 );
    TTEST( ! log.empty() );
    TTEST( log.get() == SIXTEEN_CHAR_STRING );

    log.insert( EIGHT_CHAR_STRING );
    TTEST( log.size() == 2 );
    TTEST( log.get() == SIXTEEN_CHAR_STRING EIGHT_CHAR_STRING );

    // This will cause log to over fill and the string shouldn't be added
    log.insert( HUGE_CHAR_STRING );
    TTEST( log.size() == 3 );
    TTEST( log.get() == SIXTEEN_CHAR_STRING EIGHT_CHAR_STRING );

    // This would fit in the space we've got left in the log, but because
    // the previous one didn't fit, this one shouldn't be looged either
    log.insert( EIGHT_CHAR_STRING );
    TTEST( log.size() == 4 );
    TTEST( log.get() == SIXTEEN_CHAR_STRING EIGHT_CHAR_STRING );
}