Ejemplo n.º 1
0
void create_test_times() {
	time_t tnow;

	// Create a time_t that is 10:30:30 on July 15th of this year.
	tnow = time(0);
	atm *at = atm_create_from_time_t(&tnow);
	at->loc->tm_hour = 10;
	at->loc->tm_min = 30;
	at->loc->tm_sec = 30;
	at->loc->tm_mon = 6;
	at->loc->tm_mday = 15;
	atm *at2 = atm_create_from_loctime(at->loc);
	tnow = at2->time;
	at = atm_free(at);
	at2 = atm_free(at2);

	tsecless = tnow - 1;
	tminless = tnow - 60;
	thourless = tnow - (60 * 60);
	tdayless = tnow - (60 * 60 * 24);
	tmonless = tnow - (60 * 60 * 24 * 31);
	tyearless = tnow - (60 * 60 * 24 * 366);

	atnow = atm_create_from_time_t(&tnow);
	atnow2 = atm_create_from_time_t(&tnow);
	atsecless = atm_create_from_time_t(&tsecless);
	atminless = atm_create_from_time_t(&tminless);
	athourless = atm_create_from_time_t(&thourless);
	atdayless = atm_create_from_time_t(&tdayless);
	atmonless = atm_create_from_time_t(&tmonless);
	atyearless = atm_create_from_time_t(&tyearless);
}
Ejemplo n.º 2
0
void test_free() {
	time_t t = time(0);
	atm *at = atm_create_from_time_t(&t);
	aut_assert("test_free_created", at != NULL);
	at = atm_free(at);
	aut_assert("test_free_freed", at == NULL);
	at = atm_free(at);
	aut_assert("test_free_freed", at == NULL);
}
Ejemplo n.º 3
0
/*
 * Free the memory that was allocated for an atm_range structure.
 *
 * Parameter: The time range to be freed.
 * Return:    NULL pointer.
 */
atm_range *atm_range_free(atm_range *range) {
	if(range != NULL) {
		if(range->begin != NULL) {
			range->begin = atm_free(range->begin);
		}
		if(range->end != NULL) {
			range->end = atm_free(range->end);
		}
		free(range);
	}
	return NULL;
}
Ejemplo n.º 4
0
void test_atm_create_now() {
	atm *at1 = atm_create_now();
	aut_assert("test atm_create_now", at1 != NULL);
//	printf("\nCreated from now...\n");
//	print_atm(at1);
	at1 = atm_free(at1);
}
Ejemplo n.º 5
0
/*
 * SSCOP_TERM / SOS_* Command Processor
 * 
 * Arguments:
 *	sop	pointer to sscop connection block
 *	arg1	command specific argument
 *	arg2	command specific argument
 *
 * Returns:
 *	none
 *
 */
void
sscop_term_all(struct sscop *sop, int arg1, int arg2)
{
	int		err;

	/*
	 * Set termination state
	 */
	sop->so_state = SOS_TERM;

	/*
	 * Pass the TERM down the stack
	 */
	STACK_CALL(CPCS_TERM, sop->so_lower, sop->so_tokl, sop->so_connvc,
		0, 0, err);
	if (err) {
		/*
		 * Should never happen
		 */
		sscop_abort(sop, "sscop: TERM failure\n");
		return;
	}

	/*
	 * Unlink and free the connection block
	 */
	UNLINK(sop, struct sscop, sscop_head, so_next);
	atm_free((caddr_t)sop);
	sscop_vccnt--;
	return;
}
Ejemplo n.º 6
0
/*
 * Send a RELEASE COMPLETE message
 *
 * Arguments:
 *	usp	pointer to UNISIG protocol instance block
 *	uvp	pointer to VCCB for which the RELEASE is being sent.
 *		NULL indicates that a VCCB wasn't found for a call
 *		reference value.
 *	msg	pointer to the message which triggered the send
 *	cause	the cause code for the message; a value of
 *		T_ATM_ABSENT indicates that the cause code is
 *		in the VCC's ATM attributes block
 *
 * Returns:
 *	0	success
 *	errno	error encountered
 *
 */
int
unisig_send_release_complete(struct unisig *usp, struct unisig_vccb *uvp,
			     struct unisig_msg *msg, int cause)
{
	int			err = 0;
	struct unisig_msg	*rls_cmp;
	struct ie_generic	*cause_ie;

	ATM_DEBUG4("unisig_send_release_complete usp=%p, uvp=%p, msg=%p, cause=%d\n",
			usp, uvp, msg, cause);

	/*
	 * Get memory for a RELEASE COMPLETE message
	 */
	rls_cmp = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
	if (rls_cmp == NULL) {
		return(ENOMEM);
	}
	cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
	if (cause_ie == NULL) {
		atm_free(rls_cmp);
		return(ENOMEM);
	}

	/*
	 * Fill in the RELEASE COMPLETE message
	 */
	if (uvp) {
		rls_cmp->msg_call_ref = uvp->uv_call_ref;
	} else if (msg) {
		rls_cmp->msg_call_ref = EXTRACT_CREF(msg->msg_call_ref);
	} else {
		rls_cmp->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL;
	}
	rls_cmp->msg_type = UNI_MSG_RLSC;
	rls_cmp->msg_type_flag = 0;
	rls_cmp->msg_type_action = 0;
	rls_cmp->msg_ie_caus = cause_ie;

	/*
	 * Fill out the cause IE
	 */
	cause_ie->ie_ident = UNI_IE_CAUS;
	if (cause == T_ATM_ABSENT) {
		unisig_cause_from_attr(cause_ie,
				&uvp->uv_connvc->cvc_attr);
	} else {
		cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
		unisig_cause_from_msg(cause_ie, msg, cause);
	}

	/*
	 * Send the RELEASE COMPLETE
	 */
	err = unisig_send_msg(usp, rls_cmp);
	unisig_free_msg(rls_cmp);

	return(err);
}
Ejemplo n.º 7
0
void test_atm_create_from_time_t() {
	time_t t1 = time(0);
	atm *at1 = atm_create_from_time_t(&t1);
	aut_assert("test_atm_create_from_time_t", at1 != NULL);
//	printf("\nCreated from time_t...\n");
//	print_atm(at1);
	at1 = atm_free(at1);
}
Ejemplo n.º 8
0
void free_test_times() {
	atnow = atm_free(atnow);
	atnow2 = atm_free(atnow2);
	atsecless = atm_free(atsecless);
	atminless = atm_free(atminless);
	athourless = atm_free(athourless);
	atdayless = atm_free(atdayless);
	atmonless = atm_free(atmonless);
	atyearless = atm_free(atyearless);
}
Ejemplo n.º 9
0
void test_atm_create_from_loctime() {
	time_t t1 = time(0);
	struct tm *tm1 = localtime(&t1);
	atm *at1 = atm_create_from_loctime(tm1);
	aut_assert("test_atm_create_from_loctime", at1 != NULL);
//	printf("\nCreated from localtime...\n");
//	print_atm(at1);
	at1 = atm_free(at1);
}
Ejemplo n.º 10
0
/*
 * Send a RELEASE message
 *
 * Arguments:
 *	usp	pointer to UNISIG protocol instance block
 *	uvp	pointer to VCCB for which the RELEASE is being sent
 *	msg	pointer to UNI signalling message that the RELEASE
 *		responds to (may be NULL)
 *	cause	the reason for the RELEASE; a value of
 *		T_ATM_ABSENT indicates that the cause code is
 *		in the VCC's ATM attributes block
 *
 * Returns:
 *	none
 *
 */
int
unisig_send_release(struct unisig *usp, struct unisig_vccb *uvp,
		    struct unisig_msg *msg, int cause)
{
	int			err = 0;
	struct unisig_msg	*rls_msg;
	struct ie_generic	*cause_ie;

	ATM_DEBUG2("unisig_send_release: usp=%p, uvp=%p\n",
			usp, uvp);

	/*
	 * Get memory for a RELEASE message
	 */
	rls_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
	if (rls_msg == NULL) {
		return(ENOMEM);
	}
	cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
	if (cause_ie == NULL) {
		atm_free(rls_msg);
		return(ENOMEM);
	}

	/*
	 * Fill in the RELEASE message
	 */
	rls_msg->msg_call_ref = uvp->uv_call_ref;
	rls_msg->msg_type = UNI_MSG_RLSE;
	rls_msg->msg_type_flag = 0;
	rls_msg->msg_type_action = 0;
	rls_msg->msg_ie_caus = cause_ie;

	/*
	 * Fill out the cause IE
	 */
	cause_ie->ie_ident = UNI_IE_CAUS;
	if (cause == T_ATM_ABSENT) {
		unisig_cause_from_attr(cause_ie,
				&uvp->uv_connvc->cvc_attr);
	} else {
		cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
		unisig_cause_from_msg(cause_ie, msg, cause);
	}

	/*
	 * Send the RELEASE
	 */
	err = unisig_send_msg(usp, rls_msg);
	unisig_free_msg(rls_msg);

	return(err);
}
Ejemplo n.º 11
0
void test_atm_set_original() {
	atm *at = atm_create_now();
	aut_assert("test atm_set_original 1", at != NULL && at->original == at->time);
	time_t orit = at->original;
	time_t newt = at->time + 600;
	atm_set_from_time_t(at, &newt);
	aut_assert("test atm_set_original 2", at != NULL && at->original == orit && at->time == newt);
	atm_set_original(at);
	aut_assert("test atm_set_original 3", at != NULL && at->original == at->time && at->time == orit);
//	printf("\nCreated from now...\n");
//	print_atm(at);
	at = atm_free(at);
}
Ejemplo n.º 12
0
/*
 * Process IP Network Interface Deactivation
 * 
 * Called whenever an IP network interface becomes inactive.
 *
 * Called from a critical section.
 *
 * Arguments:
 *      clp     pointer to CLS interface
 *
 * Returns:
 *      none
 *
 */
void
spansarp_ipdact(struct spanscls *clp)
{
	struct spanscls		*clp2;
	struct spansarp		*sap, *snext;
	int		i;

	/* 
	 * Delete all interface entries
	 */
	for (i = 0; i < SPANSARP_HASHSIZ; i++) {
		for (sap = spansarp_arptab[i]; sap; sap = snext) {
			snext = sap->sa_next;

			/*
			 * Clean up entries for this interface
			 */
			if (sap->sa_cls != clp)
				continue;

			/*
			 * All VCCs better be gone by now
			 */
			if (sap->sa_ivp)
				panic("spansarp_ipdact: entry not empty");

			/*
			 * Remove entry from the retry chain
			 */
			UNLINK(sap, struct spansarp, 
				spansarp_retry_head, sa_rnext);

			/*
			 * Delete entry from arp table
			 */
			SPANSARP_DELETE(sap);
			atm_free((caddr_t)sap);
		}
	}

	/*
	 * Stop aging timer if this is the last active interface
	 */
	for (clp2 = spanscls_head; clp2; clp2 = clp2->cls_next) {
		if ((clp != clp2) && (clp2->cls_ipnif))
			break;
	}
	if (clp2 == NULL)
		atm_untimeout(&spansarp_timer);
}
Ejemplo n.º 13
0
/*
 * SPANS ARP supported VCC is closing
 * 
 * This function is called just prior to a user closing a VCC which 
 * supports SPANS ARP.  We'll sever our links to the VCC and then
 * figure out how much more cleanup we need to do for now.
 *
 * Arguments:
 *	ivp	pointer to VCC's IPVCC control block
 *
 * Returns:
 *	none
 *
 */
void
spansarp_vcclose(struct ipvcc *ivp)
{
	struct spansarp	*sap;

	crit_enter();
	/*
	 * Get spansarp entry
	 */
	SPANSARP_LOOKUP(ivp->iv_dst.s_addr, sap);
	if (sap == NULL) {
		crit_exit();
		return;
	}

	/*
	 * Remove IP VCC from chain
	 */
	UNLINK(ivp, struct ipvcc, sap->sa_ivp, iv_arpnext);
	ivp->iv_arpent = NULL;

	/*
	 * If entry is currently valid or in use, not much else for us to do
	 */
	if ((sap->sa_flags & (SAF_VALID | SAF_LOCKED)) ||
	    (sap->sa_origin >= SAO_PERM)) {
		crit_exit();
		return;
	}

	/*
	 * If there are still other VCCs waiting, exit
	 */
	if (sap->sa_ivp) {
		crit_exit();
		return;
	}

	/*
	 * Noone else waiting, so remove entry from the retry chain
	 */
	UNLINK(sap, struct spansarp, spansarp_retry_head, sa_rnext);

	/*
	 * Free entry
	 */
	SPANSARP_DELETE(sap);
	atm_free((caddr_t)sap);
	crit_exit();
}
Ejemplo n.º 14
0
void test_atm_to_string() {
	atm *at = atm_create_now();
	aut_assert("test atm_to_string", at != NULL);
	char *atstr = atm_to_string(at);
	aut_assert("test atm_to_string not null", atstr != NULL);

//	print_atm(at);
//	printf("%s\n", atstr);

	char teststr[41];
	snprintf(teststr, 41, "%lu", at->time);
	aut_assert("test atm_to_string length", strlen(atstr) == strlen(teststr));
	aut_assert("test atm_to_string content", strcmp(atstr, teststr) == 0);

	at = atm_free(at);
}
Ejemplo n.º 15
0
int main(int arg, char **argv)
{
    char user_input[1000];
    if (arg != 2) {
        printf("Error opening atm initialization file\n");
        return 64;
    }
    char *token;
   char argv_cp[1024];
   strcpy(argv_cp, argv[1]);
   strtok(argv_cp, ".");
   token = strtok(NULL, ".");
   if (strcmp(token, "atm") != 0) {
    printf("Error opening atm initialization file\n");
    return 64;
   }

    ATM *atm = atm_create();
   
    //Check for command line arguements
     FILE *fp;
     fp = fopen(argv[1],"r");
    if(fp ==NULL) {
    	printf("Error opening atm initialization file\n");
	return 64;
    }
    strcpy(atm->symm_key, argv[1]);
    fclose(fp);
    printf("%s", prompt);
    fflush(stdout);

    while (fgets(user_input, 10000,stdin) != NULL)
    {
        atm_process_command(atm, user_input);
	if(atm->session == 1) {
		printf("ATM (%s): ",atm->username);	
	} else {
        printf("%s", prompt);
	}
        fflush(stdout);
    }   
	atm_free(atm);
	return EXIT_SUCCESS;
}
Ejemplo n.º 16
0
int main(int argc, char *argv[])
{
    char user_input[1000];
    FILE *atm_file;

    if(argc != 2) {
      printf("Usage: atm <filename>\n");
      exit(62);
    }

    if(strncmp(argv[1]+strlen(argv[1])-4, ".atm", 4) != 0) {
      printf("Error opening ATM initialization file\n");
      exit(64);
    }

    atm_file = fopen(argv[1], "r");
    if(!atm_file) {
      printf("Error opening ATM initialization file\n");
      exit(64);
    }

    ATM *atm = atm_create();
    fread(atm->key, sizeof(char), BLOCK_SIZE, atm_file);
    fread(atm->iv, sizeof(char), BLOCK_SIZE, atm_file);

    printf("%s", prompt);
    fflush(stdout);

    while (fgets(user_input, 10000,stdin) != NULL)
    {
        if(strlen(user_input) > 0 && strcmp(user_input, "\n") == 0) continue;
        atm_process_command(atm, user_input);
        if(atm->session) {
          printf("ATM (<%s>): ", atm->cur_user);
        } else {
          printf("%s", prompt);
        }
        fflush(stdout);
    }
    atm_free(atm);

    return EXIT_SUCCESS;
}
Ejemplo n.º 17
0
/*
 * Process a SPANS timeout
 *
 * Called when a previously scheduled spans control block timer expires.
 * Processing will based on the current SPANS state.
 *
 * Called at splnet.
 *
 * Arguments:
 *	tip	pointer to spans timer control block
 *
 * Returns:
 *	none
 *
 */
void
spans_timer(struct atm_time *tip)
{
    struct spans	*spp;
    spans_msg	*msg;
    Atm_addr_pvc	*pvcp;
    int		err;

    /*
     * Back-off to SPANS control block
     */
    spp = (struct spans *)
          ((caddr_t)tip - (int)(&((struct spans *)0)->sp_time));

    ATM_DEBUG2("spans_timer: spp=%p,state=%d\n",
               spp, spp->sp_state);

    /*
     * Process timeout based on protocol state
     */
    switch (spp->sp_state) {

    case SPANS_INIT:

        /*
         * Open signalling channel
         */
        spans_attr.nif = spp->sp_pif->pif_nif;

        spans_attr.aal.v.aal4.forward_max_SDU_size =
            ATM_NIF_MTU;
        spans_attr.aal.v.aal4.backward_max_SDU_size =
            ATM_NIF_MTU;
        spans_attr.aal.v.aal4.SSCS_type =
            T_ATM_SSCS_SSCOP_UNREL;
        spans_attr.aal.v.aal4.mid_low = 0;
        spans_attr.aal.v.aal4.mid_high = 0;

        spans_attr.called.tag = T_ATM_PRESENT;
        spans_attr.called.addr.address_format = T_ATM_PVC_ADDR;
        spans_attr.called.addr.address_length =
            sizeof(Atm_addr_pvc);
        pvcp = (Atm_addr_pvc *)spans_attr.called.addr.address;
        ATM_PVC_SET_VPI(pvcp, SPANS_SIG_VPI);
        ATM_PVC_SET_VCI(pvcp, SPANS_SIG_VCI);
        spans_attr.called.subaddr.address_format = T_ATM_ABSENT;
        spans_attr.called.subaddr.address_length = 0;

        spans_attr.traffic.v.forward.PCR_all_traffic =
            spp->sp_pif->pif_pcr;
        spans_attr.traffic.v.backward.PCR_all_traffic =
            spp->sp_pif->pif_pcr;

        err = atm_cm_connect(&spans_endpt, spp, &spans_attr,
                             &spp->sp_conn);
        if (err) {
            log(LOG_CRIT, "spans: signalling channel setup failed\n");
            return;
        }

        /*
         * Signalling channel open, start probing
         */
        spp->sp_state = SPANS_PROBE;

    /* FALLTHRU */

    case SPANS_PROBE:
    case SPANS_ACTIVE:

        /*
         * Send out SPANS_STAT_REQ message
         */
        msg = (spans_msg *)atm_allocate(&spans_msgpool);
        if (msg == NULL) {
            /* Retry later if no memory */
            SPANS_TIMER(spp, SPANS_PROBE_ERR_WAIT);
            break;
        }
        msg->sm_vers = SPANS_VERS_1_0;
        msg->sm_type = SPANS_STAT_REQ;
        msg->sm_stat_req.streq_es_epoch = spp->sp_h_epoch;
        if (spans_send_msg(spp, msg)) {
            /* Retry later if send fails */
            SPANS_TIMER(spp, SPANS_PROBE_ERR_WAIT);
            atm_free(msg);
            break;
        }
        atm_free(msg);
        spp->sp_probe_ct++;

        /*
         * Check whether we're getting an answer to our probes
         */
        if (spp->sp_state == SPANS_ACTIVE &&
                spp->sp_probe_ct > SPANS_PROBE_THRESH) {
            /*
             * Interface is down, notify VCC owners
             */
            spans_switch_reset(spp, SPANS_UNI_DOWN);

            /*
             * Set new state and increment host epoch so
             * switch knows we reset everyting.
             */
            spp->sp_state = SPANS_PROBE;
            spp->sp_h_epoch++;
            spp->sp_s_epoch = 0;
        }

        /*
         * Keep sending status requests
         */
        SPANS_TIMER(spp, SPANS_PROBE_INTERVAL);

        break;

    case SPANS_DETACH:
        /*
         * Try to terminate the SPANS signalling PVC
         */
        err = atm_cm_release(spp->sp_conn, &spans_cause);
        if (err) {
            log(LOG_ERR, "spans: can't close signalling channel\n");
        }
        break;

    default:
        log(LOG_ERR, "spans: timer state: spp=%p, state=%d\n",
            spp, spp->sp_state);
    }
}
Ejemplo n.º 18
0
/*
 * Send a STATUS message
 *
 * Arguments:
 *	usp	pointer to UNISIG protocol instance block
 *	uvp	pointer to VCCB for which the STATUS is being sent.
 *		NULL indicates that a VCCB wasn't found for a call
 *		reference value.
 *	msg	pointer to the message which triggered the send
 *	cause	the cause code to include in the message
 *
 * Returns:
 *	none
 *
 */
int
unisig_send_status(struct unisig *usp, struct unisig_vccb *uvp,
		   struct unisig_msg *msg, int cause)
{
	int			err = 0, i;
	struct unisig_msg	*stat_msg;
	struct ie_generic	*cause_ie, *clst_ie, *iep;

	ATM_DEBUG4("unisig_send_status: usp=%p, uvp=%p, msg=%p, cause=%d\n",
			usp, uvp, msg, cause);

	/*
	 * Get memory for a STATUS message
	 */
	stat_msg = (struct unisig_msg *) atm_allocate(&unisig_msgpool);
	if (stat_msg == NULL) {
		return(ENOMEM);
	}
	cause_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
	if (cause_ie == NULL) {
		atm_free(stat_msg);
		return(ENOMEM);
	}
	clst_ie = (struct ie_generic *) atm_allocate(&unisig_iepool);
	if (clst_ie == NULL) {
		atm_free(stat_msg);
		atm_free(cause_ie);
		return(ENOMEM);
	}

	/*
	 * Fill in the STATUS message
	 */
	if (uvp) {
		stat_msg->msg_call_ref = uvp->uv_call_ref;
	} else if (msg) {
		stat_msg->msg_call_ref =
				EXTRACT_CREF(msg->msg_call_ref);
	} else {
		stat_msg->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL;
	}
	stat_msg->msg_type = UNI_MSG_STAT;
	stat_msg->msg_type_flag = 0;
	stat_msg->msg_type_action = 0;
	stat_msg->msg_ie_clst = clst_ie;
	stat_msg->msg_ie_caus = cause_ie;

	/*
	 * Fill out the call state IE
	 */
	clst_ie->ie_ident = UNI_IE_CLST;
	clst_ie->ie_coding = 0;
	clst_ie->ie_flag = 0;
	clst_ie->ie_action = 0;
	if (uvp) {
		clst_ie->ie_clst_state = uvp->uv_sstate;
	} else {
		clst_ie->ie_clst_state = UNI_NULL;
	}

	/*
	 * Fill out the cause IE
	 */
	cause_ie->ie_ident = UNI_IE_CAUS;
	cause_ie->ie_coding = 0;
	cause_ie->ie_flag = 0;
	cause_ie->ie_action = 0;
	cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER;
	cause_ie->ie_caus_cause = cause;
	switch (cause) {
	case UNI_IE_CAUS_MTEXIST:
	case UNI_IE_CAUS_STATE:
		if (msg) {
			cause_ie->ie_caus_diagnostic[0] = msg->msg_type;
		}
		break;
	case UNI_IE_CAUS_MISSING:
	case UNI_IE_CAUS_IECONTENT:
	case UNI_IE_CAUS_IEEXIST:
		for (i=0, iep=msg->msg_ie_err;
				iep && i<UNI_MSG_IE_CNT;
				i++, iep = iep->ie_next) {
			if (iep->ie_err_cause == cause) {
				cause_ie->ie_caus_diagnostic[i] =
						iep->ie_ident;
			}
		}
	}

	/*
	 * Send the STATUS message
	 */
	err = unisig_send_msg(usp, stat_msg);
	unisig_free_msg(stat_msg);

	return(err);
}
Ejemplo n.º 19
0
/*
 * Process a SETUP message
 *
 * Arguments:
 *	usp	pointer to UNISIG protocol instance block
 *	msg	pointer to the SETUP message
 *
 * Returns:
 *	none
 *
 */
static void
unisig_rcv_setup(struct unisig *usp, struct unisig_msg *msg)
{
	struct unisig_vccb	*uvp = NULL;
	struct ie_generic	*iep;

	ATM_DEBUG2("unisig_rcv_setup: usp=%p, msg=%p\n", usp, msg);

	/*
	 * If we already have a VCC with the call reference,
	 * ignore the SETUP message
	 */
	uvp = unisig_find_conn(usp, EXTRACT_CREF(msg->msg_call_ref));
	if (uvp)
		return;

	/*
	 * If the call reference flag is incorrectly set, 
	 * ignore the SETUP message
	 */
	if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT)
		return;

	/*
	 * If there are missing mandatory IEs, send a
	 * RELEASE COMPLETE message and ignore the SETUP
	 */
	for (iep = msg->msg_ie_err; iep; iep = iep->ie_next) {
		if (iep->ie_err_cause == UNI_IE_CAUS_MISSING) {
			unisig_send_release_complete(usp,
					uvp, msg, UNI_IE_CAUS_MISSING);
			return;
		}
	}

	/*
	 * If there are mandatory IEs with invalid content, send a
	 * RELEASE COMPLETE message and ignore the SETUP
	 */
	for (iep = msg->msg_ie_err; iep; iep = iep->ie_next) {
		if (iep->ie_err_cause == UNI_IE_CAUS_IECONTENT) {
			unisig_send_release_complete(usp,
					uvp, msg,
					UNI_IE_CAUS_IECONTENT);
			return;
		}
	}

	/*
	 * Get a new VCCB for the connection
	 */
	uvp = (struct unisig_vccb *)atm_allocate(&unisig_vcpool);
	if (uvp == NULL) {
		return;
	}

	/*
	 * Put the VCCB on the UNISIG queue
	 */
	ENQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq);

	/*
	 * Set the state and call reference value
	 */
	uvp->uv_sstate = UNI_NULL;
	uvp->uv_call_ref = EXTRACT_CREF(msg->msg_call_ref);

	/*
	 * Pass the VCCB and message to the VC state machine
	 */
	unisig_vc_state(usp, uvp, UNI_VC_SETUP_MSG, msg);

	/*
	 * If the VCCB state is NULL, the open failed and the
	 * VCCB should be released
	 */
	if (uvp->uv_sstate == UNI_NULL) {
		DEQUEUE(uvp, struct unisig_vccb, uv_sigelem,
				usp->us_vccq);
		atm_free(uvp);
	}
Ejemplo n.º 20
0
/*
 * Process a SPANS ARP aging timer tick
 * 
 * This function is called every SPANSARP_AGING seconds, in order to age
 * all the arp table entries.
 *
 * Called from a critical section.
 *
 * Arguments:
 *	tip	pointer to spansarp aging timer control block
 *
 * Returns:
 *	none
 *
 */
static void
spansarp_aging(struct atm_time *tip)
{
	struct spansarp	*sap, *snext;
	struct ipvcc	*ivp, *inext;
	int		i;


	/*
	 * Schedule next timeout
	 */
	atm_timeout(&spansarp_timer, SPANSARP_AGING, spansarp_aging);

	/*
	 * Run through arp table bumping each entry's aging timer.
	 */
	for (i = 0; i < SPANSARP_HASHSIZ; i++) {
		for (sap = spansarp_arptab[i]; sap; sap = snext) {
			snext = sap->sa_next;

			/*
			 * Permanent (manually installed) entries aren't aged
			 */
			if (sap->sa_origin == SAO_PERM)
				continue;

			/*
			 * See if entry is valid and over-aged
			 */
			if ((sap->sa_flags & SAF_VALID) == 0)
				continue;
			if (++sap->sa_reftime < SPANSARP_MAXAGE)
				continue;

			/*
			 * Entry is now invalid, tell IP/ATM about it
			 */
			sap->sa_flags |= SAF_LOCKED;
			for (ivp = sap->sa_ivp; ivp; ivp = inext) {
				inext = ivp->iv_arpnext;
				(*ivp->iv_ipnif->inf_arpnotify)
						(ivp, MAP_INVALID);
			}
			sap->sa_flags &= ~(SAF_LOCKED | SAF_VALID);

			if (sap->sa_ivp != NULL) {
				/*
				 * Somebody still cares, so add the arp
				 * entry to the retry list.
				 */
				LINK2TAIL(sap, struct spansarp,
						spansarp_retry_head, sa_rnext);
				if ((spansarp_rtimer.ti_flag & TIF_QUEUED) == 0)
					atm_timeout(&spansarp_rtimer,
						SPANSARP_RETRY, spansarp_retry);

				/*
				 * Issue arp request for this address
				 */
				spansarp_request(sap);

			} else {
				/*
				 * Delete unused entry
				 */
				SPANSARP_DELETE(sap);
				atm_free((caddr_t)sap);
			}
		}
	}
}
Ejemplo n.º 21
0
/*
 * SPANS ARP IOCTL support
 *
 * Function will be called from a critical section.
 *
 * Arguments:
 *	code	PF_ATM sub-operation code
 *      data    pointer to code specific parameter data area
 *      arg1    pointer to code specific argument
 *
 * Returns:
 *	0	request procesed
 *	errno	error processing request - reason indicated
 *
 */
int
spansarp_ioctl(int code, caddr_t data, caddr_t arg1)
{
	struct atmaddreq	*aap;
	struct atmdelreq	*adp;
	struct atminfreq	*aip;
	struct spans		*spp;
	struct spanscls		*clp;
	struct spansarp		*sap;
	struct air_arp_rsp	aar;
	struct ip_nif		*inp;
	struct ipvcc		*ivp, *inext;
	struct in_addr		ip;
	u_long			dst;
	int			err = 0, i, buf_len;
	caddr_t			buf_addr;


	switch (code) {

	case AIOCS_ADD_ARP:
		/*
		 * Add a permanent ARP mapping
		 */
		aap = (struct atmaddreq *)data;
		clp = (struct spanscls *)arg1;
		inp = clp->cls_ipnif;
		if ((aap->aar_arp_addr.address_format != T_ATM_SPANS_ADDR) ||
		    (aap->aar_arp_origin != ARP_ORIG_PERM)) {
			err = EINVAL;
			break;
		}
		ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;

		/*
		 * See if we already have an entry for this IP address
		 */
		SPANSARP_LOOKUP(ip.s_addr, sap);
		if (sap == NULL) {
			/*
			 * No, get a new arp entry
			 */
			sap = (struct spansarp *)atm_allocate(&spansarp_pool);
			if (sap == NULL) {
				err = ENOMEM;
				break;
			}

			/*
			 * Get entry set up
			 */
			sap->sa_dstip = ip;
			ATM_ADDR_COPY(&aap->aar_arp_addr, &sap->sa_dstatm);
			sap->sa_dstatmsub.address_format = T_ATM_ABSENT;
			sap->sa_dstatmsub.address_length = 0;
			sap->sa_cls = clp;
			sap->sa_flags |= SAF_VALID;
			sap->sa_origin = SAO_PERM;

			/*
			 * Add entry to table
			 */
			SPANSARP_ADD(sap);
			break;

		}

		/*
		 * See if we're attempting to change the ATM address for
		 * this cached entry
		 */
		if ((sap->sa_dstatm.address_format != T_ATM_ABSENT) &&
		    (!ATM_ADDR_EQUAL(&aap->aar_arp_addr, &sap->sa_dstatm) ||
		     (clp != sap->sa_cls))) {

			/*
			 * Yes, notify IP/ATM that a mapping change has
			 * occurred.  IP/ATM will close any VCC's which
			 * aren't waiting for this map.
			 */
			sap->sa_flags |= SAF_LOCKED;
			for (ivp = sap->sa_ivp; ivp; ivp = inext) {
				inext = ivp->iv_arpnext;
				(*inp->inf_arpnotify)(ivp, MAP_CHANGED);
			}
			sap->sa_flags &= ~SAF_LOCKED;
		}

		/*
		 * Update the cached entry with the new data
		 */
		ATM_ADDR_COPY(&aap->aar_arp_addr, &sap->sa_dstatm);
		sap->sa_cls = clp;

		/*
		 * If this entry isn't valid, notify anyone who might
		 * be interested
		 */
		if ((sap->sa_flags & SAF_VALID) == 0) {

			sap->sa_flags |= SAF_LOCKED;
			for (ivp = sap->sa_ivp; ivp; ivp = inext) {
				inext = ivp->iv_arpnext;
				(*inp->inf_arpnotify)(ivp, MAP_VALID);
			}
			sap->sa_flags &= ~SAF_LOCKED;
		}

		/*
		 * Remove this entry from the retry chain
		 */
		UNLINK(sap, struct spansarp, spansarp_retry_head, sa_rnext);

		/*
		 * Mark the entry as permanent
		 */
		sap->sa_flags |= SAF_VALID;
		sap->sa_origin = SAO_PERM;
		break;

	case AIOCS_DEL_ARP:
		/*
		 * Delete an ARP mapping
		 */
		adp = (struct atmdelreq *)data;
		clp = (struct spanscls *)arg1;
		ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;

		/*
		 * Now find the entry to be deleted
		 */
		SPANSARP_LOOKUP(ip.s_addr, sap);
		if (sap == NULL) {
			err = ENOENT;
			break;
		}

		/*
		 * Notify all VCCs using this entry that they must finish
		 * up now.  
		 */
		sap->sa_flags |= SAF_LOCKED;
		for (ivp = sap->sa_ivp; ivp; ivp = inext) {
			inext = ivp->iv_arpnext;
			(*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
		}

		/*
		 * Now free up the entry
		 */
		UNLINK(sap, struct spansarp, spansarp_retry_head, sa_rnext);
		SPANSARP_DELETE(sap);
		atm_free((caddr_t)sap);
		break;

	case AIOCS_INF_ARP:
		/*
		 * Get ARP table information
		 */
		aip = (struct atminfreq *)data;
		spp = (struct spans *)arg1;

		if (aip->air_arp_addr.sa_family != AF_INET)
			break;
		dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;

		buf_addr = aip->air_buf_addr;
		buf_len = aip->air_buf_len;

		if ((clp = spp->sp_cls) == NULL)
			break;

		/*
		 * Run through entire arp table
		 */
		for (i = 0; i < SPANSARP_HASHSIZ; i++) {
			for (sap = spansarp_arptab[i]; sap;
						sap = sap->sa_next) {
				/*
				 * We only want entries learned
				 * from the supplied interface.
				 */
				if (sap->sa_cls != clp)
					continue;
				if ((dst != INADDR_ANY) &&
				    (dst != sap->sa_dstip.s_addr))
					continue;

				/*
				 * Make sure there's room in the user's buffer
				 */
				if (buf_len < sizeof(aar)) {
					err = ENOSPC;
					break;
				}

				/*
				 * Fill in info to be returned
				 */
				SATOSIN(&aar.aap_arp_addr)->sin_family =
					AF_INET;
				SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
					sap->sa_dstip.s_addr;
				strlcpy(aar.aap_intf,
				    clp->cls_ipnif->inf_nif->nif_if.if_xname,
				    sizeof(aar.aap_intf));
				aar.aap_flags = sap->sa_flags;
				aar.aap_origin = sap->sa_origin;
				if (sap->sa_flags & SAF_VALID)
					aar.aap_age = SPANSARP_MAXAGE - 
							sap->sa_reftime;
				else
					aar.aap_age = 0;
				ATM_ADDR_COPY(&sap->sa_dstatm, &aar.aap_addr);
				ATM_ADDR_COPY(&sap->sa_dstatmsub,
					&aar.aap_subaddr);

				/*
				 * Copy the response into the user's buffer
				 */
				if ((err = copyout((caddr_t)&aar, buf_addr, 
							sizeof(aar))) != 0)
					break;
				buf_addr += sizeof(aar);
				buf_len -= sizeof(aar);
			}
			if (err)
				break;
		}

		/*
		 * Update the buffer pointer and length
		 */
		aip->air_buf_addr = buf_addr;
		aip->air_buf_len = buf_len;
		break;

	case AIOCS_INF_ASV:
		/*
		 * Get ARP server information
		 */
		/* SPANS doesn't have an ARP server */
		break;

	default:
		err = EOPNOTSUPP;
	}

	return (err);
}
Ejemplo n.º 22
0
/*
 * Open a SPANS VCC
 *
 * Called when a user wants to open a VC.  This function will construct
 * a VCCB, create the stack requested by the user, and, if we are
 * opening an SVC, start the SPANS signalling message exchange.  The
 * user will have to wait for a notify event to be sure the SVC is fully
 * open.
 *
 * Must be called from a critical section.
 *
 * Arguments:
 *	spp	pointer to SPANS protocol instance
 *	acp	pointer to PVC's connection parameters
 *
 * Returns:
 *	0	VCC creation successful
 *	errno	VCC setup failed - reason indicated
 *
 */
int
spans_open_vcc(struct spans *spp, Atm_connvc *cvp)
{
	struct atm_pif		*pip = spp->sp_pif;
	struct spans_vccb	*svp;
	Atm_addr_pvc		*pvp;
	spans_aal		aal;
	int			err, pvc, vpi, vci;

	ATM_DEBUG2("spans_open_vcc: spp=%p, cvp=%p\n", spp, cvp);

	/*
	 * Validate user parameters. AAL and encapsulation are
	 * checked by the connection manager.
	 */

	/*
	 * Check called party address(es)
	 */
	if (cvp->cvc_attr.called.tag != T_ATM_PRESENT ||
			cvp->cvc_attr.called.addr.address_format ==
				T_ATM_ABSENT ||
			cvp->cvc_attr.called.subaddr.address_format !=
				T_ATM_ABSENT) {
		return(EINVAL);
	}
	switch (cvp->cvc_attr.called.addr.address_format) {
	case T_ATM_PVC_ADDR:
		/*
		 * Make sure VPI/VCI is valid
		 */
		pvc = 1;
		pvp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
		vpi = ATM_PVC_GET_VPI(pvp);
		vci = ATM_PVC_GET_VCI(pvp);
		if ((vpi > pip->pif_maxvpi) ||
				(vci == 0) ||
				(vci > pip->pif_maxvci)) {
			return(ERANGE);
		}

		/*
		 * Make sure VPI/VCI is not already in use
		 */
		if (spans_find_vpvc(spp, vpi, vci, 0)) {
			return(EADDRINUSE);
		}
		ATM_DEBUG2("spans_open_vcc: VPI.VCI=%d.%d\n",
				vpi, vci);
		break;

	case T_ATM_SPANS_ADDR:
		pvc = 0;
		vpi = vci = 0;

		/*
		 * Check signalling state
		 */
		if (spp->sp_state != SPANS_ACTIVE) {
			return(ENETDOWN);
		}

		/*
		 *Check destination address length
		 */
		if (cvp->cvc_attr.called.addr.address_length !=
				sizeof(spans_addr)) {
			return(EINVAL);
		}
		break;

	default:
		return(EINVAL);
	}

	/*
	 * Check that this is for the same interface SPANS uses
         */
	if (!cvp->cvc_attr.nif ||
			cvp->cvc_attr.nif->nif_pif != spp->sp_pif) {
		return(EINVAL);
	}

	/*
	 * Check AAL
	 */
	if (!spans_get_spans_aal(cvp->cvc_attr.aal.type, &aal)) {
		return(EINVAL);
	}

#ifdef NOTDEF
	/*
	 * Check encapsulation
	 */
	/* XXX -- How do we check encapsulation? */
	if (cvp->ac_encaps != ATM_ENC_NULL) {
		return(EINVAL);
	}
#endif

	/*
	 * Allocate control block for VCC
	 */
	svp = (struct spans_vccb *)atm_allocate(&spans_vcpool);
	if (svp == NULL) {
		return(ENOMEM);
	}

	/*
	 * Fill in VCCB
	 */
	if (pvc) {
		svp->sv_type = VCC_PVC | VCC_IN | VCC_OUT;
		svp->sv_vpi = vpi;
		svp->sv_vci = vci;
		svp->sv_sstate = (spp->sp_state == SPANS_ACTIVE ?
				SPANS_VC_ACTIVE : SPANS_VC_ACT_DOWN);
		svp->sv_ustate = VCCU_OPEN;
	} else {
		svp->sv_type = VCC_SVC | VCC_OUT;
		spans_addr_copy(cvp->cvc_attr.called.addr.address,
				&svp->sv_conn.con_dst);
		spans_addr_copy(spp->sp_addr.address,
				&svp->sv_conn.con_src);
		svp->sv_conn.con_dsap = SPANS_SAP_IP;
		svp->sv_conn.con_ssap = spans_ephemeral_sap(spp);
		svp->sv_sstate = SPANS_VC_POPEN;
		svp->sv_ustate = VCCU_POPEN;
	}
	svp->sv_proto = ATM_SIG_SPANS;
	svp->sv_pif = spp->sp_pif;
	svp->sv_nif = cvp->cvc_attr.nif;
	svp->sv_connvc = cvp;
	svp->sv_spans_aal = aal;
	svp->sv_tstamp = time_second;

	/*
	 * Put VCCB on SPANS queue
	 */
	ENQUEUE(svp, struct spans_vccb, sv_sigelem, spp->sp_vccq);

	/*
	 * Link VCCB to VCC connection block
	 */
	cvp->cvc_vcc = (struct vccb *) svp;

	/*
	 * Start the SPANS message exchange if this is an SVC
	 */
	if (!pvc) {
		svp->sv_retry = 0;
		svp->sv_spans_qos.rsc_peak = 1;
		svp->sv_spans_qos.rsc_mean = 1;
		svp->sv_spans_qos.rsc_burst = 1;
		err = spans_send_open_req(spp, svp);
		if (err) {
			/*
			 * On error, delete the VCCB
			 */
			DEQUEUE(svp, struct spans_vccb, sv_sigelem,
					spp->sp_vccq);
			cvp->cvc_vcc = NULL;
			atm_free((caddr_t)svp);
			return(err);
		} else {
Ejemplo n.º 23
0
/*
 * Drain the Stack Queue
 * 
 * Dequeues and processes entries from the global stack queue.  
 *
 * Arguments:
 *	none
 *
 * Returns:
 *	none
 *
 */
void
atm_stack_drain(void)
{
	struct stackq_entry	*sqp, *qprev, *qnext;
	int		cnt;

	crit_enter();
	/*
	 * Loop thru entire queue until queue is empty
	 *	(but panic rather loop forever)
	 */
	do {
		cnt = 0;
		qprev = NULL;
		for (sqp = atm_stackq_head; sqp; ) {

			/*
			 * Got an eligible entry, do STACK_CALL stuff
			 */
			if (sqp->sq_cmd & STKCMD_UP) {
				if (sqp->sq_connvc->cvc_downcnt) {

					/*
					 * Cant process now, skip it
					 */
					qprev = sqp;
					sqp = sqp->sq_next;
					continue;
				}

				/*
				 * OK, dispatch the call
				 */
				sqp->sq_connvc->cvc_upcnt++;
				(*sqp->sq_func)(sqp->sq_cmd, 
						sqp->sq_token,
						sqp->sq_arg1,
						sqp->sq_arg2);
				sqp->sq_connvc->cvc_upcnt--;
			} else {
				if (sqp->sq_connvc->cvc_upcnt) {

					/*
					 * Cant process now, skip it
					 */
					qprev = sqp;
					sqp = sqp->sq_next;
					continue;
				}

				/*
				 * OK, dispatch the call
				 */
				sqp->sq_connvc->cvc_downcnt++;
				(*sqp->sq_func)(sqp->sq_cmd, 
						sqp->sq_token,
						sqp->sq_arg1,
						sqp->sq_arg2);
				sqp->sq_connvc->cvc_downcnt--;
			}

			/*
			 * Dequeue processed entry and free it
			 */
			cnt++;
			qnext = sqp->sq_next;
			if (qprev)
				qprev->sq_next = qnext;
			else
				atm_stackq_head = qnext;
			if (qnext == NULL)
				atm_stackq_tail = qprev;
			atm_free((caddr_t)sqp);
			sqp = qnext;
		}
	} while (cnt > 0);

	/*
	 * Make sure entire queue was drained
	 */
	if (atm_stackq_head != NULL)
		panic("atm_stack_drain: Queue not emptied");
	crit_exit();
}