Пример #1
0
static int
route_call(layer4_t *l4)
{
	layer4_t	*newl4;

	fprintf(stderr, "%s: msn ", __FUNCTION__);
	display_NR_IE(l4->msn);
	fprintf(stderr, "%s:  nr ", __FUNCTION__);
	display_NR_IE(l4->nr);
	if (l4->usednr->typ == NR_TYPE_INTERN) {
		newl4 = get_free_channel(&kern_if, -1, NULL);
		if (!newl4) {
			l4->cause_loc = CAUSE_LOC_PNET_LOCUSER;
			l4->cause_val = CAUSE_USER_BUSY;
			l4->progress = PROGRESS_TONE;
			if_link(l4->nst, man_down, MAN_CLEAR_CALL | REQUEST,
				l4->channel, 0, NULL, 0);
			return(0);
		}
		l4->sdata = newl4;
		l4->rdata = newl4;
		newl4->sdata = l4;
		newl4->rdata = l4;
		l4->sbuf = &newl4->rbuf;
		newl4->sbuf = &l4->rbuf;
		newl4->msn[0] = l4->usednr->len +1;
		newl4->msn[1] = 0x81;
		memcpy(&newl4->msn[2], l4->usednr->nr, l4->usednr->len);
		if (l4->msn[0])
			memcpy(newl4->nr, l4->msn, l4->msn[0] + 1);
		newl4->l1_prot = ISDN_PID_L1_B_64TRANS;
		if_link(newl4->nst, man_down, MAN_SETUP | REQUEST,
			newl4->channel, 0, NULL, 0);
	} else if (l4->usednr->typ == NR_TYPE_AUDIO) {
		l4->sdata = NULL;
		l4->rdata = NULL;
		strcpy(l4->display,"connect to AUDIO");
		do_connect(l4);
		l4->display[0] = 0;
		deactivate_bchannel(l4);
		setup_bchannel_rawdev(l4);
		activate_bchannel(l4);
	} else if (l4->usednr->typ == NR_TYPE_VOIP) {
		l4->sdata = NULL;
		l4->rdata = NULL;
		sprintf(l4->display,"calling %s", l4->usednr->name);
		do_alert(l4);
		sprintf(l4->display,"connect to %s", l4->usednr->name);
		do_connect(l4);
		l4->display[0] = 0;
		deactivate_bchannel(l4);
		setup_bchannel_rawdev(l4);
		activate_bchannel(l4);
	}
	return(0);
}
Пример #2
0
static int
clear_call(layer4_t *l4)
{
	if (l4->sdata) {
		layer4_t *peer = l4->sdata;
		
		if (l4->cause_val) {
			peer->cause_loc = l4->cause_loc;
			peer->cause_val = l4->cause_val;
		} else {
			peer->cause_loc = CAUSE_LOC_PNET_LOCUSER;
			peer->cause_val = CAUSE_NORMALUNSPECIFIED;
		}
		peer->progress = PROGRESS_TONE;
		peer->sbuf = NULL;
		peer->sdata = NULL;
		peer->rdata = NULL;
		if (peer->nst)
			if_link(peer->nst, man_down, MAN_CLEAR_CALL |
				REQUEST, peer->channel, 0, NULL, 0);
	}
	l4->sdata = NULL;
	l4->rdata = NULL;
	l4->sbuf = NULL;
	return(0);
}
Пример #3
0
static int
do_alert(layer4_t *l4)
{
	if_link(l4->nst, man_down, MAN_ALERT | REQUEST,
		l4->channel, 0, NULL, 0);
	return(0);
}
Пример #4
0
static int
do_connect(layer4_t *l4)
{
	if_link(l4->nst, man_down, MAN_CONNECT | REQUEST,
		l4->channel, 0, NULL, 0);
	return(0);
}
Пример #5
0
static int
l3down(layer3_t *l3, u_int prim, int dinfo, struct sk_buff *skb) {
	int err = -EINVAL;

	if (!skb)
		err = if_link(&l3->inst.down, prim, dinfo, 0, NULL, 0);
	else
		err = if_newhead(&l3->inst.down, prim, dinfo, skb);
	return(err);
}
Пример #6
0
static int
do_disconnect(layer4_t *l4)
{
	l4->cause_loc = CAUSE_LOC_PNET_LOCUSER;
	l4->cause_val = CAUSE_NORMAL_CLEARING;
	l4->progress = PROGRESS_TONE;
	if_link(l4->nst, man_down, MAN_CLEAR_CALL | REQUEST,
		l4->channel, 0, NULL, 0);
	return(0);
}
Пример #7
0
static int
connect_call(layer4_t *l4)
{
	strcpy(l4->display,"connect ack");
	if_link(l4->nst, man_down, MAN_CONNECT | RESPONSE,
		l4->channel, 0, NULL, 0);
	del_timer(&timer1);
	if (l4->sdata)
		do_connect(l4->sdata);
	return(0);
}
Пример #8
0
int
mISDN_l3up(l3_process_t *l3p, u_int prim, struct sk_buff *skb)
{
	layer3_t *l3;
	int err = -EINVAL;

	if (!l3p)
		return(-EINVAL);
	l3 = l3p->l3;
	if (!skb)
		err = if_link(&l3->inst.up, prim, l3p->id, 0, NULL, 0);
	else
		err = if_newhead(&l3->inst.up, prim, l3p->id, skb);
	return(err);
}
Пример #9
0
/*
 * Read a list of gateways from /etc/gateways and add them to our tables.
 *
 * This file contains a list of "remote" gateways.  That is usually
 * a gateway which we cannot immediately determine if it is present or
 * not as we can do for those provided by directly connected hardware.
 *
 * If a gateway is marked "passive" in the file, then we assume it
 * does not understand RIP and assume it is always present.  Those
 * not marked passive are treated as if they were directly connected
 * and assumed to be broken if they do not send us advertisements.
 * All remote interfaces are added to our list, and those not marked
 * passive are sent routing updates.
 *
 * A passive interface can also be local, hardware interface exempt
 * from RIP.
 */
void
gwkludge(void)
{
#define	STR2(x)	#x
#define	STR(x)	STR2(x)

#define	NETHOST_LEN	4
#define	DNAME_LEN	MAXHOSTNAMELEN
#define	GNAME_LEN	MAXHOSTNAMELEN
#define	QUAL_LEN	8

	FILE *fp;
	char *p, *lptr;
	const char *cp;
	char lbuf[PARMS_MAXLINELEN], net_host[NETHOST_LEN + 1];
	char dname[MAXHOSTNAMELEN + 1];
	char gname[MAXHOSTNAMELEN + 1], qual[QUAL_LEN +1];
	struct interface *ifp;
	uint32_t dst, netmask, gate;
	int n;
	uint32_t lnum;
	struct stat sb;
	uint32_t state, metric;
	boolean_t default_dst;


	fp = fopen(PATH_GATEWAYS, "r");
	if (fp == NULL)
		return;

	if (0 > fstat(fileno(fp), &sb)) {
		msglog("fstat() failed: %s for  "PATH_GATEWAYS,
		    rip_strerror(errno));
		(void) fclose(fp);
		return;
	}

	for (lnum = 1; ; lnum++) {
		if (NULL == fgets(lbuf, sizeof (lbuf), fp))
			break;

		/* Eliminate the /n character at the end of the lbuf */
		if (strlen(lbuf) > 0)
			lbuf[strlen(lbuf) - 1] = '\0';

		/* Move lptr to the first non-space character */
		for (lptr = lbuf; isspace(*lptr); lptr++)
			;

		if (*lptr == '#' || *lptr == '\0')
			continue;

		/* Move p to the end of the line */
		p = lptr + strlen(lptr) - 1;

		/* Skip all trailing spaces except escaped space */
		while (p > lptr && (isspace(*p) && *(p-1) != '\\'))
			p--;

		/* truncate the line to remove trailing spaces */
		*++p = '\0';

		/* notice newfangled parameter lines */
		if (strncasecmp("net", lptr, 3) != 0 &&
		    strncasecmp("host", lptr, 4) != 0) {
			cp = parse_parms(lptr, (sb.st_uid == 0 &&
			    !(sb.st_mode&(S_IRWXG|S_IRWXO))));
			if (cp != 0)
				msglog("%s in line %u of "PATH_GATEWAYS,
				    cp, lnum);
			continue;
		}

		/*
		 * Processes lines of the follwoing format:
		 * net|host <name>[/mask] gateway <Gname> metric <value>
		 * passive|active|extern
		 */
		qual[0] = '\0';
		n = sscanf(lptr, "%"STR(NETHOST_LEN)"s %"STR(DNAME_LEN)
		    "[^ \t] gateway %"STR(GNAME_LEN)"[^ / \t] metric %u %"
		    STR(QUAL_LEN)"s\n", net_host, dname, gname, &metric, qual);
		if (n != 4 && n != 5) {
			msglog("bad "PATH_GATEWAYS" entry \"%s\"; %d values",
			    lptr, n);
			continue;
		}
		if (metric >= HOPCNT_INFINITY) {
			msglog("bad metric in "PATH_GATEWAYS" entry \"%s\"",
			    lptr);
			continue;
		}
		default_dst = _B_FALSE;
		if (strcasecmp(net_host, "host") == 0) {
			if (!gethost(dname, &dst)) {
				msglog("bad host \"%s\" in "PATH_GATEWAYS
				    " entry \"%s\"", dname, lptr);
				continue;
			}
			netmask = HOST_MASK;
		} else if (strcasecmp(net_host, "net") == 0) {
			if (!getnet(dname, &dst, &netmask)) {
				msglog("bad net \"%s\" in "PATH_GATEWAYS
				    " entry \"%s\"", dname, lptr);
				continue;
			}
			default_dst = (dst == RIP_DEFAULT);
			dst = htonl(dst); /* make network # into IP address */
		} else {
			msglog("bad \"%s\" in "PATH_GATEWAYS
			    " entry \"%s\"", net_host, lptr);
			continue;
		}

		if (!gethost(gname, &gate)) {
			msglog("bad gateway \"%s\" in "PATH_GATEWAYS
			    " entry \"%s\"", gname, lptr);
			continue;
		}

		if (strcasecmp(qual, "passive") == 0) {
			/*
			 * Passive entries are not placed in our tables,
			 * only the kernel's, so we don't copy all of the
			 * external routing information within a net.
			 * Internal machines should use the default
			 * route to a suitable gateway (like us).
			 */
			state = IS_REMOTE | IS_PASSIVE;
			if (metric == 0)
				metric = 1;

		} else if (strcasecmp(qual, "external") == 0) {
			/*
			 * External entries are handled by other means
			 * such as EGP, and are placed only in the daemon
			 * tables to prevent overriding them with something
			 * else.
			 */
			(void) strlcpy(qual, "external", sizeof (qual));
			state = IS_REMOTE | IS_PASSIVE | IS_EXTERNAL;
			if (metric == 0)
				metric = 1;

		} else if (strcasecmp(qual, "active") == 0 ||
		    qual[0] == '\0') {

			if (default_dst) {
				msglog("bad net \"%s\" in "PATH_GATEWAYS
				    " entry \"%s\"-- cannot be default",
				    dname, lptr);
				continue;
			}

			if (metric != 0) {
				/*
				 * Entries that are neither "passive" nor
				 * "external" are "remote" and must behave
				 * like physical interfaces.  If they are not
				 * heard from regularly, they are deleted.
				 */
				state = IS_REMOTE;
			} else {
				/*
				 * "remote" entries with a metric of 0
				 * are aliases for our own interfaces
				 */
				state = IS_REMOTE | IS_PASSIVE | IS_ALIAS;
			}

		} else {
			msglog("bad "PATH_GATEWAYS" entry \"%s\";"
			    " unknown type %s", lptr, qual);
			continue;
		}

		if (0 != (state & (IS_PASSIVE | IS_REMOTE)))
			state |= IS_NO_RDISC;
		if (state & IS_PASSIVE)
			state |= IS_NO_RIP;


		if (default_dst) {
			addroutefordefault(dst, gate, netmask, metric,
			    ((state & IS_EXTERNAL)? RTS_EXTERNAL : 0));
			continue;
		}

		ifp = check_dup(NULL, gate, dst, netmask, 0, _B_FALSE);
		if (ifp != NULL) {
			msglog("duplicate "PATH_GATEWAYS" entry \"%s\"", lptr);
			continue;
		}

		ifp = rtmalloc(sizeof (*ifp), "gwkludge()");
		(void) memset(ifp, 0, sizeof (*ifp));

		ifp->int_state = state;
		if (netmask == HOST_MASK)
			ifp->int_if_flags = IFF_POINTOPOINT | IFF_UP;
		else
			ifp->int_if_flags = IFF_UP;
		ifp->int_act_time = NEVER;
		ifp->int_addr = gate;
		ifp->int_dstaddr = dst;
		ifp->int_mask = netmask;
		ifp->int_ripv1_mask = netmask;
		ifp->int_std_mask = std_mask(gate);
		ifp->int_net = ntohl(dst);
		ifp->int_std_net = ifp->int_net & ifp->int_std_mask;
		ifp->int_std_addr = htonl(ifp->int_std_net);
		ifp->int_metric = metric;
		if (!(state & IS_EXTERNAL) &&
		    ifp->int_mask != ifp->int_std_mask)
			ifp->int_state |= IS_SUBNET;
		(void) snprintf(ifp->int_name, sizeof (ifp->int_name),
		    "remote(%s)", gname);

		if_link(ifp, 0);
	}

	(void) fclose(fp);

	/*
	 * After all of the parameter lines have been read,
	 * apply them to any remote interfaces.
	 */
	for (ifp = ifnet; NULL != ifp; ifp = ifp->int_next) {
		get_parms(ifp);

		tot_interfaces++;
		if (!IS_RIP_OFF(ifp->int_state))
			rip_interfaces++;
		if (!IS_RIP_OUT_OFF(ifp->int_state))
			ripout_interfaces++;

		trace_if("Add", ifp);
	}

}
Пример #10
0
static int
l2up_create(layer2_t *l2, u_int prim, int dinfo, int len, void *arg)
{
	return(if_link(l2->nst, l2->nst->l2_l3, prim, dinfo, len, arg, 0));
}