예제 #1
0
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;		
	}
예제 #2
0
/* skip over a domain name */
static const u_char *
ns_nskip(register const u_char *cp)
{
	register u_char i;

	if (!TTEST2(*cp, 1))
		return (NULL);
	i = *cp++;
	while (i) {
		if ((i & INDIR_MASK) == INDIR_MASK)
			return (cp + 1);
		if ((i & INDIR_MASK) == EDNS0_MASK) {
			int bitlen, bytelen;

			if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL)
				return(NULL); /* unknown ELT */
			if (!TTEST2(*cp, 1))
				return (NULL);
			if ((bitlen = *cp++) == 0)
				bitlen = 256;
			bytelen = (bitlen + 7) / 8;
			cp += bytelen;
		} else
			cp += i;
		if (!TTEST2(*cp, 1))
			return (NULL);
		i = *cp++;
	}
	return (cp);
}
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;
    }
예제 #4
0
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;		
	}
예제 #5
0
static int
handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
{
	if (!TTEST2(*p, 2))
		return 0;
	if (length < 2)
		return 0;
	if (eflag) {
		printf(": ");
	} else {
		printf(" (%s): ", etheraddr_string(pmh->sa));
	}
	switch (p[0]) {
	case 0: printf("Spectrum Management Act#%d", p[1]); break;
	case 1: printf("QoS Act#%d", p[1]); break;
	case 2: printf("DLS Act#%d", p[1]); break;
	case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
	case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
	case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break;
	case 15: printf("Interwork Act#%d", p[1]); break;
	case 16: printf("Resource Act#%d", p[1]); break;
	case 17: printf("Proxy Act#%d", p[1]); break;
	case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break;
	case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break;
	case 127: printf("Vendor Act#%d", p[1]); break;
	default:
		printf("Reserved(%d) Act#%d", p[0], p[1]);
		break;
	}
	return 1;
}
예제 #6
0
static int
handle_deauth(const struct mgmt_header_t *pmh, const u_char *p)
{
	struct mgmt_body_t  pbody;
	int offset = 0;
	const char *reason = NULL;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
		return 0;
	pbody.reason_code = EXTRACT_LE_16BITS(p);
	offset += IEEE802_11_REASON_LEN;

	reason = (pbody.reason_code < NUM_REASONS)
			? reason_text[pbody.reason_code]
			: "Reserved";

	if (eflag) {
		printf(": %s", reason);
	} else {
		printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
	}
	return 1;
}
예제 #7
0
static int
handle_reassoc_request(const u_char *p)
{
	struct mgmt_body_t pbody;
	int offset = 0;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
	    IEEE802_11_AP_LEN))
		return 0;
	pbody.capability_info = EXTRACT_LE_16BITS(p);
	offset += IEEE802_11_CAPINFO_LEN;
	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_LISTENINT_LEN;
	memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
	offset += IEEE802_11_AP_LEN;

	parse_elements(&pbody, p, offset);

	PRINT_SSID(pbody);
	printf(" AP : %s", etheraddr_string( pbody.ap ));

	return 1;
}
예제 #8
0
static int
handle_probe_response(const u_char *p)
{
	struct mgmt_body_t  pbody;
	int offset = 0;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
	    IEEE802_11_CAPINFO_LEN))
		return 0;

	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
	offset += IEEE802_11_TSTAMP_LEN;
	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_BCNINT_LEN;
	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_CAPINFO_LEN;

	parse_elements(&pbody, p, offset);

	PRINT_SSID(pbody);
	PRINT_RATES(pbody);
	PRINT_DS_CHANNEL(pbody);

	return 1;
}
예제 #9
0
void
carp_print(register const u_char *bp, register u_int len, int ttl)
{
	int version, type;
	char *type_s;

	TCHECK(bp[0]);
	version = (bp[0] & 0xf0) >> 4;
	type = bp[0] & 0x0f;
	if (type == 1)
		type_s = "advertise";
	else
		type_s = "unknown";
	printf("CARPv%d-%s %d: ", version, type_s, len);
	if (ttl != 255)
		printf("[ttl=%d!] ", ttl);
	if (version != 2 || type != 1)
		return;
	TCHECK(bp[2]);
	TCHECK(bp[5]);
	printf("vhid=%d advbase=%d advskew=%d demote=%d",
	    bp[1], bp[5], bp[2], bp[4]);
	if (vflag) {
		if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0))
			printf(" (bad carp cksum %x!)",
				EXTRACT_16BITS(&bp[6]));
	}
	return;
trunc:
	printf("[|carp]");
}
예제 #10
0
static int
handle_assoc_response(const u_char *p)
{
	struct mgmt_body_t pbody;
	int offset = 0;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
	    IEEE802_11_AID_LEN))
		return 0;
	pbody.capability_info = EXTRACT_LE_16BITS(p);
	offset += IEEE802_11_CAPINFO_LEN;
	pbody.status_code = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_STATUS_LEN;
	pbody.aid = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_AID_LEN;

	parse_elements(&pbody, p, offset);

	printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
	    CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
	    (pbody.status_code < NUM_STATUSES
		? status_text[pbody.status_code]
		: "n/a"));

	return 1;
}
예제 #11
0
/* print a <domain-name> */
static const u_char *
blabel_print(const u_char *cp)
{
	int bitlen, slen, b;
	const u_char *bitp, *lim;
	char tc;

	if (!TTEST2(*cp, 1))
		return(NULL);
	if ((bitlen = *cp) == 0)
		bitlen = 256;
	slen = (bitlen + 3) / 4;
	lim = cp + 1 + slen;

	/* print the bit string as a hex string */
	printf("\\[x");
	for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) {
		TCHECK(*bitp);
		printf("%02x", *bitp);
	}
	if (b > 4) {
		TCHECK(*bitp);
		tc = *bitp++;
		printf("%02x", tc & (0xff << (8 - b)));
	} else if (b > 0) {
		TCHECK(*bitp);
		tc = *bitp++;
		printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
	}
/**
@SYMTestCaseID          PDS-EFM-CT-4058
@SYMTestCaseDesc        Querying and modifying a feature during restore operation. 
                        Verify that a response is returned from the server during restore.
@SYMTestPriority        High
@SYMTestActions         Start simulating restore operation
                        Create a thread that will:
                        Modify a feature and verify that a response (KErrServerBusy) is received 
                        Query a feature and verify that a response is received (doesn't matter what the result is)
                        The thread should finished in less than 2 seconds.
                        Otherwise the test fail.          
@SYMTestExpectedResults Test must not fail
@SYMREQ                 
*/  
void TestRestoreResponseL()
    {
        _LIT(KThreadName, "RstTh");
        featMgrIsResponsive = EFalse;
        
        CFeatMgrBURSim* simulate = CFeatMgrBURSim::NewLC();
        RThread testThread;
        TRequestStatus testStatus;
        CleanupClosePushL( testThread );
        
        //Needs to ensure server is started before simulating backup operation
        RFeatureControl rfc;
        TTEST2( rfc.Connect(), KErrNone ); //This will start the server if not already started
        rfc.Close();
        
        simulate->Simulate_CheckRegFileL();
        
        // Simulate a restore
        RDebug::Print(_L("Simulating Restore of FeatMgr\r\n"));
        simulate->Simulate_StartRestoreL();

        TEST2( testThread.Create(KThreadName, &TestThreadL, 0x2000, 0x1000, 0x10000, NULL, EOwnerProcess), KErrNone );
        testThread.Logon(testStatus);
        TEST2( testStatus.Int(), KRequestPending );
        testThread.Resume();
        // Wait for 1.5 second for the query thread to finish. 
        RDebug::Print(_L("+++:MainThread: Wait for query and modification completion...\r\n"));
        MainThreadCrS.Wait(threadTimeout);
        // If query is responsive within the 1.5 second frame the following check should pass.
        TEST (featMgrIsResponsive);
        simulate->Simulate_EndRestoreL();
        
        CleanupStack::PopAndDestroy(&testThread);
        CleanupStack::PopAndDestroy(simulate);
    }
예제 #13
0
파일: print-802_11.c 프로젝트: OPSF/uClinux
static int
handle_probe_response(const u_char *p)
{
	struct mgmt_body_t  pbody;
	int offset = 0;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
	    IEEE802_11_CAPINFO_LEN))
		return 0;

	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
	offset += IEEE802_11_TSTAMP_LEN;
	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_BCNINT_LEN;
	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_CAPINFO_LEN;

	if (!parse_elements(&pbody, p, offset))
		return 0;

	printf(" (");
	fn_print(pbody.ssid.ssid, NULL);
	printf(") ");
	PRINT_RATES(pbody);
	printf(" CH: %u%s", pbody.ds.channel,
	    CAPABILITY_PRIVACY(pbody.capability_info) ? ", PRIVACY" : "" );

	return 1;
}
예제 #14
0
static int
handle_assoc_request(const u_char *p, u_int length)
{
	struct mgmt_body_t pbody;
	int offset = 0;
	int ret;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
		return 0;
	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
		return 0;
	pbody.capability_info = EXTRACT_LE_16BITS(p);
	offset += IEEE802_11_CAPINFO_LEN;
	length -= IEEE802_11_CAPINFO_LEN;
	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_LISTENINT_LEN;
	length -= IEEE802_11_LISTENINT_LEN;

	ret = parse_elements(&pbody, p, offset, length);

	PRINT_SSID(pbody);
	PRINT_RATES(pbody);
	return ret;
}
예제 #15
0
static int
handle_beacon(const u_char *p, u_int length)
{
	struct mgmt_body_t pbody;
	int offset = 0;
	int ret;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
	    IEEE802_11_CAPINFO_LEN))
		return 0;
	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
	    IEEE802_11_CAPINFO_LEN)
		return 0;
	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
	offset += IEEE802_11_TSTAMP_LEN;
	length -= IEEE802_11_TSTAMP_LEN;
	pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_BCNINT_LEN;
	length -= IEEE802_11_BCNINT_LEN;
	pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_CAPINFO_LEN;
	length -= IEEE802_11_CAPINFO_LEN;

	ret = parse_elements(&pbody, p, offset, length);

	PRINT_SSID(pbody);
	PRINT_RATES(pbody);
	printf(" %s",
	    CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
	PRINT_DS_CHANNEL(pbody);

	return ret;
}
예제 #16
0
void
lwapp_data_print(const u_char *pptr, u_int len) {

    const struct lwapp_transport_header *lwapp_trans_header;
    const u_char *tptr;
    int tlen;

    tptr=pptr;

    /* check if enough bytes for AP identity */
    if (!TTEST2(*tptr, 6))
        goto trunc;
    lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    TCHECK(*lwapp_trans_header);

    /*
     * Sanity checking of the header.
     */
    if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
        printf("LWAPP version %u packet not supported",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version));
        return;
    }

    /* non-verbose */
    if (vflag < 1) {
        printf("LWAPPv%u, %s frame, Flags [%s], length %u",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
               LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
               bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
               len);
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */
    tlen=EXTRACT_16BITS(lwapp_trans_header->length);

    printf("LWAPPv%u, %s frame, Radio-id  %u, Flags [%s], Frag-id  %u, length %u",
           LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
           LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
           LWAPP_EXTRACT_RID(lwapp_trans_header->version),
           bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
           lwapp_trans_header->frag_id,
           tlen);

    tptr+=sizeof(const struct lwapp_transport_header);
    tlen-=sizeof(const struct lwapp_transport_header);

    /* FIX - An IEEE 802.11 frame follows - hexdump for now */
    print_unknown_data(tptr, "\n\t", tlen);

    return;

 trunc:
    printf("\n\t\t packet exceeded snapshot");
}
예제 #17
0
void
vrrp_print(register const u_char *bp, register u_int len, int ttl)
{
    int version, type, auth_type;
    const char *type_s;

    TCHECK(bp[0]);
    version = (bp[0] & 0xf0) >> 4;
    type = bp[0] & 0x0f;
    type_s = tok2str(type2str, "unknown type (%u)", type);
    printf("VRRPv%u, %s", version, type_s);
    if (ttl != 255)
        printf(", (ttl %u)", ttl);
    if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT)
        return;
    TCHECK(bp[2]);
    printf(", vrid %u, prio %u", bp[1], bp[2]);
    TCHECK(bp[5]);
    auth_type = bp[4];
    printf(", authtype %s", tok2str(auth2str, NULL, auth_type));
    printf(", intvl %us, length %u", bp[5],len);
    if (vflag) {
        int naddrs = bp[3];
        int i;
        char c;

        if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0))
            printf(", (bad vrrp cksum %x)",
                   EXTRACT_16BITS(&bp[6]));
        printf(", addrs");
        if (naddrs > 1)
            printf("(%d)", naddrs);
        printf(":");
        c = ' ';
        bp += 8;
        for (i = 0; i < naddrs; i++) {
            TCHECK(bp[3]);
            printf("%c%s", c, ipaddr_string(bp));
            c = ',';
            bp += 4;
        }
        if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
            TCHECK(bp[7]);
            printf(" auth \"");
            if (fn_printn(bp, 8, snapend)) {
                printf("\"");
                goto trunc;
            }
            printf("\"");
        }
    }
    return;
trunc:
    printf("[|vrrp]");
}
예제 #18
0
static int
mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
    const u_char *p, u_int length)
{
	switch (FC_SUBTYPE(fc)) {
	case ST_ASSOC_REQUEST:
		printf("Assoc Request");
		return handle_assoc_request(p, length);
	case ST_ASSOC_RESPONSE:
		printf("Assoc Response");
		return handle_assoc_response(p, length);
	case ST_REASSOC_REQUEST:
		printf("ReAssoc Request");
		return handle_reassoc_request(p, length);
	case ST_REASSOC_RESPONSE:
		printf("ReAssoc Response");
		return handle_reassoc_response(p, length);
	case ST_PROBE_REQUEST:
		printf("Probe Request");
		return handle_probe_request(p, length);
	case ST_PROBE_RESPONSE:
		printf("Probe Response");
		return handle_probe_response(p, length);
	case ST_BEACON:
		printf("Beacon");
		return handle_beacon(p, length);
	case ST_ATIM:
		printf("ATIM");
		return handle_atim();
	case ST_DISASSOC:
		printf("Disassociation");
		return handle_disassoc(p, length);
	case ST_AUTH:
		printf("Authentication");
		if (!TTEST2(*p, 3))
			return 0;
		if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
			printf("Authentication (Shared-Key)-3 ");
			return wep_print(p);
		}
		return handle_auth(p, length);
	case ST_DEAUTH:
		printf("DeAuthentication");
		return handle_deauth(pmh, p, length);
		break;
	case ST_ACTION:
		printf("Action");
		return handle_action(pmh, p, length);
		break;
	default:
		printf("Unhandled Management subtype(%x)",
		    FC_SUBTYPE(fc));
		return 1;
	}
}
예제 #19
0
/*
 * RFC 2338:
 *     0                   1                   2                   3
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs|
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |   Auth Type   |   Adver Int   |          Checksum             |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                         IP Address (1)                        |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                            .                                  |
 *    |                            .                                  |
 *    |                            .                                  |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                         IP Address (n)                        |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                     Authentication Data (1)                   |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                     Authentication Data (2)                   |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
void
vrrp_print(register const u_char *bp, register u_int len, int ttl)
{
	int version, type, auth_type;
	char *type_s;

	TCHECK(bp[0]);
	version = (bp[0] & 0xf0) >> 4;
	type = bp[0] & 0x0f;
	if (type == 1)
		type_s = "advertise";
	else
		type_s = "unknown";
	printf("VRRPv%d-%s %d: ", version, type_s, len);
	if (ttl != 255)
		printf("[ttl=%d!] ", ttl);
	if (version != 2 || type != 1)
		return;
	TCHECK(bp[2]);
	printf("vrid=%d prio=%d", bp[1], bp[2]);
	TCHECK(bp[5]);
	auth_type = bp[4];
	if (auth_type != 0)
		printf(" authtype=%d", auth_type);
	printf(" intvl=%d", bp[5]);
	if (vflag) {
		int naddrs = bp[3];
		int i;
		char c;

		if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0))
			printf(" (bad vrrp cksum %x!)",
				EXTRACT_16BITS(&bp[6]));
		printf(" addrs");
		if (naddrs > 1)
			printf("(%d)", naddrs);
		printf(":");
		c = ' ';
		bp += 8;
		for (i = 0; i < naddrs; i++) {
			TCHECK(bp[3]);
			printf("%c%s", c, ipaddr_string(bp));
			c = ',';
			bp += 4;
		}
		if (auth_type == 1) { /* simple text password */
			TCHECK(bp[7]);
			printf(" auth %.8s", bp);
		}
	}
	return;
trunc:
	printf("[|vrrp]");
}
예제 #20
0
static int
handle_auth(const u_char *p, u_int length)
{
	struct mgmt_body_t  pbody;
	int offset = 0;
	int ret;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, 6))
		return 0;
	if (length < 6)
		return 0;
	pbody.auth_alg = EXTRACT_LE_16BITS(p);
	offset += 2;
	length -= 2;
	pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
	offset += 2;
	length -= 2;
	pbody.status_code = EXTRACT_LE_16BITS(p + offset);
	offset += 2;
	length -= 2;

	ret = parse_elements(&pbody, p, offset, length);

	if ((pbody.auth_alg == 1) &&
	    ((pbody.auth_trans_seq_num == 2) ||
	     (pbody.auth_trans_seq_num == 3))) {
		printf(" (%s)-%x [Challenge Text] %s",
		    (pbody.auth_alg < NUM_AUTH_ALGS)
			? auth_alg_text[pbody.auth_alg]
			: "Reserved",
		    pbody.auth_trans_seq_num,
		    ((pbody.auth_trans_seq_num % 2)
		        ? ((pbody.status_code < NUM_STATUSES)
			       ? status_text[pbody.status_code]
			       : "n/a") : ""));
		return ret;
	}
	printf(" (%s)-%x: %s",
	    (pbody.auth_alg < NUM_AUTH_ALGS)
		? auth_alg_text[pbody.auth_alg]
		: "Reserved",
	    pbody.auth_trans_seq_num,
	    (pbody.auth_trans_seq_num % 2)
	        ? ((pbody.status_code < NUM_STATUSES)
		    ? status_text[pbody.status_code]
	            : "n/a")
	        : "");

	return ret;
}
예제 #21
0
static int
wep_print(const u_char *p)
{
	u_int32_t iv;

	if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
		return 0;
	iv = EXTRACT_LE_32BITS(p);

	printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
	    IV_KEYID(iv));

	return 1;
}
예제 #22
0
static int
ctrl_body_print(u_int16_t fc, const u_char *p)
{
	switch (FC_SUBTYPE(fc)) {
	case CTRL_PS_POLL:
		printf("Power Save-Poll");
		if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
			return 0;
		printf(" AID(%x)",
		    EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
		break;
	case CTRL_RTS:
		printf("Request-To-Send");
		if (!TTEST2(*p, CTRL_RTS_HDRLEN))
			return 0;
		if (!eflag)
			printf(" TA:%s ",
			    etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
		break;
	case CTRL_CTS:
		printf("Clear-To-Send");
		if (!TTEST2(*p, CTRL_CTS_HDRLEN))
			return 0;
		if (!eflag)
			printf(" RA:%s ",
			    etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
		break;
	case CTRL_ACK:
		printf("Acknowledgment");
		if (!TTEST2(*p, CTRL_ACK_HDRLEN))
			return 0;
		if (!eflag)
			printf(" RA:%s ",
			    etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
		break;
	case CTRL_CF_END:
		printf("CF-End");
		if (!TTEST2(*p, CTRL_END_HDRLEN))
			return 0;
		if (!eflag)
			printf(" RA:%s ",
			    etheraddr_string(((const struct ctrl_end_t *)p)->ra));
		break;
	case CTRL_END_ACK:
		printf("CF-End+CF-Ack");
		if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
			return 0;
		if (!eflag)
			printf(" RA:%s ",
			    etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
		break;
	default:
		printf("Unknown Ctrl Subtype");
	}
	return 1;
}
예제 #23
0
파일: print-802_11.c 프로젝트: OPSF/uClinux
static int
handle_disassoc(const u_char *p)
{
	struct mgmt_body_t  pbody;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_REASON_LEN))
		return 0;
	pbody.reason_code = EXTRACT_LE_16BITS(p);

	printf(": %s",
	    (pbody.reason_code < 10) ? reason_text[pbody.reason_code]
	                             : "Reserved" );

	return 1;
}
예제 #24
0
int handle_beacon(const uchar *p, u_int length, struct rcv_pkt * paket)
{
    struct mgmt_body_t pbody;
    int offset = 0;
    int ret;
    memset(&pbody, 0, sizeof(pbody));
    if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + IEEE802_11_CAPINFO_LEN))
        return 0;
    if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
            IEEE802_11_CAPINFO_LEN)
        return 0;
    memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
    offset += IEEE802_11_TSTAMP_LEN;
    length -= IEEE802_11_TSTAMP_LEN;
    pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
    offset += IEEE802_11_BCNINT_LEN;
    length -= IEEE802_11_BCNINT_LEN;
    pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
    offset += IEEE802_11_CAPINFO_LEN;
    length -= IEEE802_11_CAPINFO_LEN;

    ret = parse_elements(&pbody, p, offset, length,paket);
    if (pbody.ssid_present) {
        fn_print(pbody.ssid.ssid, NULL,paket);
    }
    if (pbody.ds_present) {
        paket->p.mgmt_pkt.channel=pbody.ds.channel;
//       printf("packet channel = %d\n",pbody.ds.channel);
    }
    paket->p.mgmt_pkt.cap_privacy=  CAPABILITY_PRIVACY(pbody.capability_info) ? 1 :0 ;
    //  printf("%s \n",   CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");

    u_int8_t _r;
    if (pbody.rates_present) {
        _r= pbody.rates.rate[pbody.rates.length -1] ;
        paket->p.mgmt_pkt.rate_max=(float)((.5 * ((_r) & 0x7f)));
        //    printf("packet rate is %f \n", paket->p.mgmt_pkt.rate_max);
    }
    else {
        paket->p.mgmt_pkt.rate_max=0.0; // undefined rate, because of bad fcs (might be a reason)
    }
    paket->p.mgmt_pkt.cap_ess_ibss = paket->p.mgmt_pkt.cap_ess_ibss=  CAPABILITY_ESS(pbody.capability_info) ? 1:2;
    return ret;
}
예제 #25
0
/*
 * Print out an NFS file handle and return a pointer to following word.
 * If packet was truncated, return 0.
 */
static const u_int32_t *
parsefh(register const u_int32_t *dp, int v3)
{
	u_int len;

	if (v3) {
		TCHECK(dp[0]);
		len = EXTRACT_32BITS(dp) / 4;
		dp++;
	} else
		len = NFSX_V2FH / 4;

	if (TTEST2(*dp, len * sizeof(*dp))) {
		nfs_printfh(dp, len);
		return (dp + len);
	}
trunc:
	return (NULL);
}
예제 #26
0
파일: print-802_11.c 프로젝트: OPSF/uClinux
static int
mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
    const u_char *p)
{
	printf("%s", subtype_text[FC_SUBTYPE(fc)]);

	switch (FC_SUBTYPE(fc)) {
	case ST_ASSOC_REQUEST:
		return handle_assoc_request(p);
	case ST_ASSOC_RESPONSE:
		return handle_assoc_response(p);
	case ST_REASSOC_REQUEST:
		return handle_reassoc_request(p);
	case ST_REASSOC_RESPONSE:
		return handle_reassoc_response(p);
	case ST_PROBE_REQUEST:
		return handle_probe_request(p);
	case ST_PROBE_RESPONSE:
		return handle_probe_response(p);
	case ST_BEACON:
		return handle_beacon(p);
	case ST_ATIM:
		return handle_atim();
	case ST_DISASSOC:
		return handle_disassoc(p);
	case ST_AUTH:
		if (!TTEST2(*p, 3))
			return 0;
		if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
			printf("Authentication (Shared-Key)-3 ");
			return wep_print(p);
		}
		return handle_auth(p);
	case ST_DEAUTH:
		return handle_deauth(pmh, p);
		break;
	default:
		printf("Unhandled Management subtype(%x)",
		    FC_SUBTYPE(fc));
		return 1;
	}
}
예제 #27
0
void
carp_print(register const u_char *bp, register u_int len, int ttl)
{
	int version, type;
	const char *type_s;

	TCHECK(bp[0]);
	version = (bp[0] & 0xf0) >> 4;
	type = bp[0] & 0x0f;
	if (type == 1)
		type_s = "advertise";
	else
		type_s = "unknown";
	printf("CARPv%d-%s %d: ", version, type_s, len);
	if (ttl != 255)
		printf("[ttl=%d!] ", ttl);
	if (version != 2 || type != 1)
		return;
	TCHECK(bp[2]);
	TCHECK(bp[5]);
	printf("vhid=%d advbase=%d advskew=%d authlen=%d ",
	    bp[1], bp[5], bp[2], bp[3]);
	if (vflag) {
		struct cksum_vec vec[1];
		vec[0].ptr = (const u_int8_t *)bp;
		vec[0].len = len;
		if (TTEST2(bp[0], len) && in_cksum(vec, 1))
			printf(" (bad carp cksum %x!)",
				EXTRACT_16BITS(&bp[6]));
	}
	printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8]));

	return;
trunc:
	printf("[|carp]");
}
예제 #28
0
파일: print-802_11.c 프로젝트: OPSF/uClinux
static int
handle_assoc_request(const u_char *p)
{
	struct mgmt_body_t pbody;
	int offset = 0;

	memset(&pbody, 0, sizeof(pbody));

	if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
		return 0;
	pbody.capability_info = EXTRACT_LE_16BITS(p);
	offset += IEEE802_11_CAPINFO_LEN;
	pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
	offset += IEEE802_11_LISTENINT_LEN;

	if (!parse_elements(&pbody, p, offset))
		return 0;

	printf(" (");
	fn_print(pbody.ssid.ssid, NULL);
	printf(")");
	PRINT_RATES(pbody);
	return 1;
}
예제 #29
0
void
vqp_print(register const u_char *pptr, register u_int len) 
{
    const struct vqp_common_header_t *vqp_common_header;
    const struct vqp_obj_tlv_t *vqp_obj_tlv;

    const u_char *tptr;
    u_int16_t vqp_obj_len;
    u_int32_t vqp_obj_type;
    int tlen;
    u_int8_t nitems;

    tptr=pptr;
    tlen = len;
    vqp_common_header = (const struct vqp_common_header_t *)pptr;
    TCHECK(*vqp_common_header);

    /*
     * Sanity checking of the header.
     */
    if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) {
	printf("VQP version %u packet not supported",
               VQP_EXTRACT_VERSION(vqp_common_header->version));
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type */
    if (vflag < 1) {
        printf("VQPv%u %s Message, error-code %s (%u), length %u",
               VQP_EXTRACT_VERSION(vqp_common_header->version),
               tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
               tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	       vqp_common_header->error_code,
               len);
        return;
    }
    
    /* ok they seem to want to know everything - lets fully decode it */
    nitems = vqp_common_header->nitems;
    printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u",
           VQP_EXTRACT_VERSION(vqp_common_header->version),
	   tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
	   tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	   vqp_common_header->error_code,
           EXTRACT_32BITS(&vqp_common_header->sequence),
           nitems,
           len);

    /* skip VQP Common header */
    tptr+=sizeof(const struct vqp_common_header_t);
    tlen-=sizeof(const struct vqp_common_header_t);

    while (nitems > 0 && tlen > 0) {

        vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
        vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
        vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
        tptr+=sizeof(struct vqp_obj_tlv_t);
        tlen-=sizeof(struct vqp_obj_tlv_t);

        printf("\n\t  %s Object (0x%08x), length %u, value: ",
               tok2str(vqp_obj_values, "Unknown", vqp_obj_type),
               vqp_obj_type, vqp_obj_len);

        /* basic sanity check */
        if (vqp_obj_type == 0 || vqp_obj_len ==0) {
            return;
        }

        /* did we capture enough for fully decoding the object ? */
        if (!TTEST2(*tptr, vqp_obj_len)) 
            goto trunc;

        switch(vqp_obj_type) {
	case VQP_OBJ_IP_ADDRESS:
            printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr));
            break;
            /* those objects have similar semantics - fall through */
        case VQP_OBJ_PORT_NAME:
	case VQP_OBJ_VLAN_NAME:
	case VQP_OBJ_VTP_DOMAIN:
	case VQP_OBJ_ETHERNET_PKT:
            safeputs((const char *)tptr, vqp_obj_len);
            break;
            /* those objects have similar semantics - fall through */
	case VQP_OBJ_MAC_ADDRESS:
	case VQP_OBJ_MAC_NULL:
	      printf("%s", etheraddr_string(tptr));
              break;
        default:
            if (vflag <= 1)
                print_unknown_data(tptr, "\n\t    ", vqp_obj_len);
            break;
        }
	tptr += vqp_obj_len;
	tlen -= vqp_obj_len;
	nitems--;
    }
    return;
trunc:
    printf("\n\t[|VQP]");
}
예제 #30
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('>');
}