Example #1
0
/*
 * Do a remote procedure call (RPC) and wait for its reply.
 * If from_p is non-null, then we are doing broadcast, and
 * the address from whence the response came is saved there.
 * data:	input/output
 * from_p:	output
 */
int
krpc_call(struct sockaddr_in *sa, u_int prog, u_int vers, u_int func,
    struct mbuf **data, struct mbuf **from_p, int retries)
{
	struct socket *so;
	struct sockaddr_in *sin;
	struct mbuf *m, *nam, *mhead, *from, *mopt;
	struct rpc_call *call;
	struct rpc_reply *reply;
	struct uio auio;
	int error, rcvflg, timo, secs, len;
	static u_int32_t xid = 0;
	char addr[INET_ADDRSTRLEN];
	int *ip;
	struct timeval tv;

	/*
	 * Validate address family.
	 * Sorry, this is INET specific...
	 */
	if (sa->sin_family != AF_INET)
		return (EAFNOSUPPORT);

	/* Free at end if not null. */
	nam = mhead = NULL;
	from = NULL;

	/*
	 * Create socket and set its receive timeout.
	 */
	if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0)))
		goto out;

	m = m_get(M_WAIT, MT_SOOPTS);
	tv.tv_sec = 1;
	tv.tv_usec = 0;
	memcpy(mtod(m, struct timeval *), &tv, sizeof tv);
	m->m_len = sizeof(tv);
	if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m)))
		goto out;

	/*
	 * Enable broadcast if necessary.
	 */
	if (from_p) {
		int32_t *on;
		m = m_get(M_WAIT, MT_SOOPTS);
		on = mtod(m, int32_t *);
		m->m_len = sizeof(*on);
		*on = 1;
		if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m)))
			goto out;
	}

	/*
	 * Bind the local endpoint to a reserved port,
	 * because some NFS servers refuse requests from
	 * non-reserved (non-privileged) ports.
	 */
	MGET(mopt, M_WAIT, MT_SOOPTS);
	mopt->m_len = sizeof(int);
	ip = mtod(mopt, int *);
	*ip = IP_PORTRANGE_LOW;
	error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
	if (error)
		goto out;

	MGET(m, M_WAIT, MT_SONAME);
	sin = mtod(m, struct sockaddr_in *);
	sin->sin_len = m->m_len = sizeof (struct sockaddr_in);
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = INADDR_ANY;
	sin->sin_port = htons(0);
	error = sobind(so, m, &proc0);
	m_freem(m);
	if (error) {
		printf("bind failed\n");
		goto out;
	}

	MGET(mopt, M_WAIT, MT_SOOPTS);
	mopt->m_len = sizeof(int);
	ip = mtod(mopt, int *);
	*ip = IP_PORTRANGE_DEFAULT;
	error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
	if (error)
		goto out;

	/*
	 * Setup socket address for the server.
	 */
	nam = m_get(M_WAIT, MT_SONAME);
	sin = mtod(nam, struct sockaddr_in *);
	bcopy((caddr_t)sa, (caddr_t)sin, (nam->m_len = sa->sin_len));

	/*
	 * Prepend RPC message header.
	 */
	mhead = m_gethdr(M_WAIT, MT_DATA);
	mhead->m_next = *data;
	call = mtod(mhead, struct rpc_call *);
	mhead->m_len = sizeof(*call);
	bzero((caddr_t)call, sizeof(*call));
	/* rpc_call part */
	xid = krpc_get_xid();
	call->rp_xid = txdr_unsigned(xid);
	/* call->rp_direction = 0; */
	call->rp_rpcvers = txdr_unsigned(2);
	call->rp_prog = txdr_unsigned(prog);
	call->rp_vers = txdr_unsigned(vers);
	call->rp_proc = txdr_unsigned(func);
	/* rpc_auth part (auth_unix as root) */
	call->rpc_auth.authtype = txdr_unsigned(RPCAUTH_UNIX);
	call->rpc_auth.authlen  = txdr_unsigned(sizeof(struct auth_unix));
	/* rpc_verf part (auth_null) */
	call->rpc_verf.authtype = 0;
	call->rpc_verf.authlen  = 0;

	/*
	 * Setup packet header
	 */
	len = 0;
	m = mhead;
	while (m) {
		len += m->m_len;
		m = m->m_next;
	}
	mhead->m_pkthdr.len = len;
	mhead->m_pkthdr.rcvif = NULL;

	/*
	 * Send it, repeatedly, until a reply is received,
	 * but delay each re-send by an increasing amount.
	 * If the delay hits the maximum, start complaining.
	 */
	for (timo = 0; retries; retries--) {
		/* Send RPC request (or re-send). */
		m = m_copym(mhead, 0, M_COPYALL, M_WAIT);
		if (m == NULL) {
			error = ENOBUFS;
			goto out;
		}
		error = sosend(so, nam, NULL, m, NULL, 0);
		if (error) {
			printf("krpc_call: sosend: %d\n", error);
			goto out;
		}
		m = NULL;

		/* Determine new timeout. */
		if (timo < MAX_RESEND_DELAY)
			timo++;
		else
			printf("RPC timeout for server %s (0x%x) prog %u\n",
			    inet_ntop(AF_INET, &sin->sin_addr,
				addr, sizeof(addr)),
			    ntohl(sin->sin_addr.s_addr), prog);

		/*
		 * Wait for up to timo seconds for a reply.
		 * The socket receive timeout was set to 1 second.
		 */
		secs = timo;
		while (secs > 0) {
			if (from) {
				m_freem(from);
				from = NULL;
			}
			if (m) {
				m_freem(m);
				m = NULL;
			}
			auio.uio_resid = len = 1<<16;
			auio.uio_procp = NULL;
			rcvflg = 0;
			error = soreceive(so, &from, &auio, &m, NULL, &rcvflg,
			    0);
			if (error == EWOULDBLOCK) {
				secs--;
				continue;
			}
			if (error)
				goto out;
			len -= auio.uio_resid;

			/* Does the reply contain at least a header? */
			if (len < MIN_REPLY_HDR)
				continue;
			if (m->m_len < MIN_REPLY_HDR)
				continue;
			reply = mtod(m, struct rpc_reply *);

			/* Is it the right reply? */
			if (reply->rp_direction != txdr_unsigned(RPC_REPLY))
				continue;

			if (reply->rp_xid != txdr_unsigned(xid))
				continue;

			/* Was RPC accepted? (authorization OK) */
			if (reply->rp_astatus != 0) {
				error = fxdr_unsigned(u_int32_t, reply->rp_errno);
				printf("rpc denied, error=%d\n", error);
				continue;
			}

			/* Did the call succeed? */
			if (reply->rp_status != 0) {
				error = fxdr_unsigned(u_int32_t, reply->rp_status);
				printf("rpc denied, status=%d\n", error);
				continue;
			}

			goto gotreply;	/* break two levels */

		} /* while secs */
	} /* forever send/receive */

	error = ETIMEDOUT;
	goto out;

 gotreply:

	/*
	 * Get RPC reply header into first mbuf,
	 * get its length, then strip it off.
	 */
	len = sizeof(*reply);
	if (m->m_len < len) {
		m = m_pullup(m, len);
		if (m == NULL) {
			error = ENOBUFS;
			goto out;
		}
	}
	reply = mtod(m, struct rpc_reply *);
	if (reply->rp_auth.authtype != 0) {
		len += fxdr_unsigned(u_int32_t, reply->rp_auth.authlen);
		len = (len + 3) & ~3; /* XXX? */
	}
	m_adj(m, len);

	/* result */
	*data = m;
	if (from_p && error == 0) {
		*from_p = from;
		from = NULL;
	}

 out:
	if (nam) m_freem(nam);
	if (mhead) m_freem(mhead);
	if (from) m_freem(from);
	soclose(so);
	return error;
}
Example #2
0
static void bootp_reply(struct bootp_t *bp)
{
    BOOTPClient *bc;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr dns_addr;
    int dhcp_msg_type, val;
    uint8_t *q;
    int freply_nack = 0;

    /* extract exact DHCP msg type */
    dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
    dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
    
    if (dhcp_msg_type == 0)
        dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
        
    if (dhcp_msg_type == DHCPRELEASE) {
        release_addr(&bp->bp_ciaddr);
        dprintf("released addr=%08lx\n", ntohl(bp->bp_ciaddr.s_addr));
        /* This message is not to be answered in any way. */
        return;
    }

    if (dhcp_msg_type != DHCPDISCOVER && 
        dhcp_msg_type != DHCPREQUEST)
        return;
    /* XXX: this is a hack to get the client mac address */
    memcpy(client_ethaddr, bp->bp_hwaddr, 6);
    
    if ((m = m_get()) == NULL)
        return;
    m->m_data += if_maxlinkhdr;
    rbp = (struct bootp_t *)m->m_data;
    m->m_data += sizeof(struct udpiphdr);
    memset(rbp, 0, sizeof(struct bootp_t));

    if (dhcp_msg_type == DHCPDISCOVER) {
        bc = get_new_addr(&daddr.sin_addr);
        if (!bc) {
            dprintf("no address left\n");
            return;
        }
        memcpy(bc->macaddr, client_ethaddr, 6);
    } else {
        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
        if (!bc) {
            /* if never assigned, reply DHCPNACK to BROADCAST.
               (windows fix because it remembers its address). */
            daddr.sin_addr.s_addr = htonl(0xffffffff);
            freply_nack = 1;
            dprintf("reply NACK\n");
        }
    }
    dprintf("offered addr=%08lx\n", ntohl(daddr.sin_addr.s_addr));

    saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    rbp->bp_op = BOOTP_REPLY;
    rbp->bp_xid = bp->bp_xid;
    rbp->bp_htype = 1;
    rbp->bp_hlen = 6;
    memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);

    if (freply_nack)
        rbp->bp_yiaddr.s_addr = htonl(0); /* When NACK, IP address is 0. */
    else
        rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

    q = rbp->bp_vend;
    memcpy(q, rfc1533_cookie, 4);
    q += 4;

    if (dhcp_msg_type == DHCPDISCOVER) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPOFFER;
    } else if (dhcp_msg_type == DHCPREQUEST) {
        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        if (freply_nack)
            *q++ = DHCPNACK;
        else
            *q++ = DHCPACK;
    }
        
    if (dhcp_msg_type == DHCPDISCOVER ||
        ((dhcp_msg_type == DHCPREQUEST) && !freply_nack)) {
        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0x00;
        
        *q++ = RFC1533_GATEWAY;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;
        
        *q++ = RFC1533_DNS;
        *q++ = 4;
        dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
        memcpy(q, &dns_addr, 4);
        q += 4;

        *q++ = RFC2132_LEASE_TIME;
        *q++ = 4;
        val = htonl(LEASE_TIME);
        memcpy(q, &val, 4);
        q += 4;

        if (*slirp_hostname) {
            val = strlen(slirp_hostname);
            *q++ = RFC1533_HOSTNAME;
            *q++ = val;
            memcpy(q, slirp_hostname, val);
            q += val;
        }
    }
    *q++ = RFC1533_END;
    
    m->m_len = sizeof(struct bootp_t) - 
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Example #3
0
void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
{
    Slirp *slirp = m->slirp;
    struct mbuf *t;
    struct ip6 *ip = mtod(m, struct ip6 *);

    DEBUG_CALL("icmp6_send_error");
    DEBUG_ARGS((dfd, " type = %d, code = %d\n", type, code));

    if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) ||
            IN6_IS_ADDR_UNSPECIFIED(&ip->ip_src)) {
        /* TODO icmp error? */
        return;
    }

    t = m_get(slirp);

    /* IPv6 packet */
    struct ip6 *rip = mtod(t, struct ip6 *);
    rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
    rip->ip_dst = ip->ip_src;
#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
    char addrstr[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN);
    DEBUG_ARG("target = %s", addrstr);
#endif

    rip->ip_nh = IPPROTO_ICMPV6;
    const int error_data_len = min(m->m_len,
            IF_MTU - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
    rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
    t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);

    /* ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = type;
    ricmp->icmp6_code = code;
    ricmp->icmp6_cksum = 0;

    switch (type) {
    case ICMP6_UNREACH:
    case ICMP6_TIMXCEED:
        ricmp->icmp6_err.unused = 0;
        break;
    case ICMP6_TOOBIG:
        ricmp->icmp6_err.mtu = htonl(IF_MTU);
        break;
    case ICMP6_PARAMPROB:
        /* TODO: Handle this case */
        break;
    default:
        g_assert_not_reached();
        break;
    }
    t->m_data += ICMP6_ERROR_MINLEN;
    memcpy(t->m_data, m->m_data, error_data_len);

    /* Checksum */
    t->m_data -= ICMP6_ERROR_MINLEN;
    t->m_data -= sizeof(struct ip6);
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}
Example #4
0
void ellipseevolve(MAT *f, double *xc0, double *yc0, double *r0, double *t, int Np, double Er, double Ey) {
	/*
	% ELLIPSEEVOLVE evolves a parametric snake according
	%  to some energy constraints.
	%
	% INPUTS:
	%   f............potential surface
	%   xc0,yc0......initial center position
	%   r0,t.........initial radii & angle vectors (with Np elements each)
	%   Np...........number of snaxel points per snake
	%   Er...........expected radius
	%   Ey...........expected y position
	%
	% OUTPUTS
	%   xc0,yc0.......final center position
	%   r0...........final radii
	%
	% Matlab code written by: DREW GILLIAM (based on work by GANG DONG /
	%                                                        NILANJAN RAY)
	% Ported to C by: MICHAEL BOYER
	*/
	
	
	// Constants
	double deltax = 0.2;
	double deltay = 0.2;
	double deltar = 0.2; 
	double converge = 0.1;
	double lambdaedge = 1;
	double lambdasize = 0.2;
	double lambdapath = 0.05;
	int iterations = 1000;      // maximum number of iterations

	int i, j;

	// Initialize variables
	double xc = *xc0;
	double yc = *yc0;
	double *r = (double *) malloc(sizeof(double) * Np);
	for (i = 0; i < Np; i++) r[i] = r0[i];
	
	// Compute the x- and y-gradients of the MGVF matrix
	MAT *fx = gradient_x(f);
	MAT *fy = gradient_y(f);
	
	// Normalize the gradients
	int fh = f->m, fw = f->n;
	for (i = 0; i < fh; i++) {
		for (j = 0; j < fw; j++) {
			double temp_x = m_get_val(fx, i, j);
			double temp_y = m_get_val(fy, i, j);
			double fmag = sqrt((temp_x * temp_x) + (temp_y * temp_y));
			m_set_val(fx, i, j, temp_x / fmag);
			m_set_val(fy, i, j, temp_y / fmag);
		}
	}
	
	double *r_old = (double *) malloc(sizeof(double) * Np);
	VEC *x = v_get(Np);
	VEC *y = v_get(Np);
	
	
	// Evolve the snake
	int iter = 0;
	double snakediff = 1.0;
	while (iter < iterations && snakediff > converge) {
		
		// Save the values from the previous iteration
		double xc_old = xc, yc_old = yc;
		for (i = 0; i < Np; i++) {
			r_old[i] = r[i];
		}
		
		// Compute the locations of the snaxels
		for (i = 0; i < Np; i++) {
			v_set_val(x, i, xc + r[i] * cos(t[i]));
			v_set_val(y, i, yc + r[i] * sin(t[i]));
		}
		
		// See if any of the points in the snake are off the edge of the image
		double min_x = v_get_val(x, 0), max_x = v_get_val(x, 0);
		double min_y = v_get_val(y, 0), max_y = v_get_val(y, 0);
		for (i = 1; i < Np; i++) {
			double x_i = v_get_val(x, i);
			if (x_i < min_x) min_x = x_i;
			else if (x_i > max_x) max_x = x_i;
			double y_i = v_get_val(y, i);
			if (y_i < min_y) min_y = y_i;
			else if (y_i > max_y) max_y = y_i;
		}
		if (min_x < 0.0 || max_x > (double) fw - 1.0 || min_y < 0 || max_y > (double) fh - 1.0) break;
		
		
		// Compute the length of the snake		
		double L = 0.0;
		for (i = 0; i < Np - 1; i++) {
			double diff_x = v_get_val(x, i + 1) - v_get_val(x, i);
			double diff_y = v_get_val(y, i + 1) - v_get_val(y, i);
			L += sqrt((diff_x * diff_x) + (diff_y * diff_y));
		}
		double diff_x = v_get_val(x, 0) - v_get_val(x, Np - 1);
		double diff_y = v_get_val(y, 0) - v_get_val(y, Np - 1);
		L += sqrt((diff_x * diff_x) + (diff_y * diff_y));
		
		// Compute the potential surface at each snaxel
		MAT *vf  = linear_interp2(f,  x, y);
		MAT *vfx = linear_interp2(fx, x, y);
		MAT *vfy = linear_interp2(fy, x, y);
		
		// Compute the average potential surface around the snake
		double vfmean  = sum_m(vf ) / L;
		double vfxmean = sum_m(vfx) / L;
		double vfymean = sum_m(vfy) / L;
		
		// Compute the radial potential surface		
		int m = vf->m, n = vf->n;
		MAT *vfr = m_get(m, n);
		for (i = 0; i < n; i++) {
			double vf_val  = m_get_val(vf,  0, i);
			double vfx_val = m_get_val(vfx, 0, i);
			double vfy_val = m_get_val(vfy, 0, i);
			double x_val = v_get_val(x, i);
			double y_val = v_get_val(y, i);
			double new_val = (vf_val + vfx_val * (x_val - xc) + vfy_val * (y_val - yc) - vfmean) / L;
			m_set_val(vfr, 0, i, new_val);
		}		
		
		// Update the snake center and snaxels
		xc =  xc + (deltax * lambdaedge * vfxmean);
		yc = (yc + (deltay * lambdaedge * vfymean) + (deltay * lambdapath * Ey)) / (1.0 + deltay * lambdapath);
		double r_diff = 0.0;
		for (i = 0; i < Np; i++) {
			r[i] = (r[i] + (deltar * lambdaedge * m_get_val(vfr, 0, i)) + (deltar * lambdasize * Er)) /
			       (1.0 + deltar * lambdasize);
			r_diff += fabs(r[i] - r_old[i]);
		}
		
		// Test for convergence
		snakediff = fabs(xc - xc_old) + fabs(yc - yc_old) + r_diff;
		
		// Free temporary matrices
		m_free(vf);
		m_free(vfx);
		m_free(vfy);
		m_free(vfr);
	    
		iter++;
	}
	
	// Set the return values
	*xc0 = xc;
	*yc0 = yc;
	for (i = 0; i < Np; i++)
		r0[i] = r[i];
	
	// Free memory
	free(r); free(r_old);
	v_free( x); v_free( y);
	m_free(fx); m_free(fy);
}
Example #5
0
static int
kttcp_soreceive(struct socket *so, unsigned long long slen,
    unsigned long long *done, struct lwp *l, int *flagsp)
{
	struct mbuf *m, **mp;
	int flags, len, error, offset, moff, type;
	long long orig_resid, resid;
	const struct protosw *pr;
	struct mbuf *nextrecord;

	pr = so->so_proto;
	mp = NULL;
	type = 0;
	resid = orig_resid = slen;
	if (flagsp)
		flags = *flagsp &~ MSG_EOR;
	else
 		flags = 0;
	if (flags & MSG_OOB) {
		m = m_get(M_WAIT, MT_DATA);
		solock(so);
		error = (*pr->pr_usrreqs->pr_recvoob)(so, m, flags & MSG_PEEK);
		sounlock(so);
		if (error)
			goto bad;
		do {
			resid -= min(resid, m->m_len);
			m = m_free(m);
		} while (resid && error == 0 && m);
 bad:
		if (m)
			m_freem(m);
		return (error);
	}
	if (mp)
		*mp = NULL;
	solock(so);
 restart:
	if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
		return (error);
	m = so->so_rcv.sb_mb;
	/*
	 * If we have less data than requested, block awaiting more
	 * (subject to any timeout) if:
	 *   1. the current count is less than the low water mark,
	 *   2. MSG_WAITALL is set, and it is possible to do the entire
	 *	receive operation at once if we block (resid <= hiwat), or
	 *   3. MSG_DONTWAIT is not set.
	 * If MSG_WAITALL is set but resid is larger than the receive buffer,
	 * we have to do the receive in sections, and thus risk returning
	 * a short count if a timeout or signal occurs after we start.
	 */
	if (m == NULL || (((flags & MSG_DONTWAIT) == 0 &&
	    so->so_rcv.sb_cc < resid) &&
	    (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
	    ((flags & MSG_WAITALL) && resid <= so->so_rcv.sb_hiwat)) &&
	    m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) {
#ifdef DIAGNOSTIC
		if (m == NULL && so->so_rcv.sb_cc)
			panic("receive 1");
#endif
		if (so->so_error) {
			if (m)
				goto dontblock;
			error = so->so_error;
			if ((flags & MSG_PEEK) == 0)
				so->so_error = 0;
			goto release;
		}
		if (so->so_state & SS_CANTRCVMORE) {
			if (m)
				goto dontblock;
			else
				goto release;
		}
		for (; m; m = m->m_next)
			if (m->m_type == MT_OOBDATA  || (m->m_flags & M_EOR)) {
				m = so->so_rcv.sb_mb;
				goto dontblock;
			}
		if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
		    (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
			error = ENOTCONN;
			goto release;
		}
		if (resid == 0)
			goto release;
		if ((so->so_state & SS_NBIO) ||
		    (flags & (MSG_DONTWAIT|MSG_NBIO))) {
			error = EWOULDBLOCK;
			goto release;
		}
		sbunlock(&so->so_rcv);
		error = sbwait(&so->so_rcv);
		if (error) {
			sounlock(so);
			return (error);
		}
		goto restart;
	}
 dontblock:
	/*
	 * On entry here, m points to the first record of the socket buffer.
	 * While we process the initial mbufs containing address and control
	 * info, we save a copy of m->m_nextpkt into nextrecord.
	 */
#ifdef notyet /* XXXX */
	if (uio->uio_lwp)
		uio->uio_lwp->l_ru.ru_msgrcv++;
#endif
	KASSERT(m == so->so_rcv.sb_mb);
	SBLASTRECORDCHK(&so->so_rcv, "kttcp_soreceive 1");
	SBLASTMBUFCHK(&so->so_rcv, "kttcp_soreceive 1");
	nextrecord = m->m_nextpkt;
	if (pr->pr_flags & PR_ADDR) {
#ifdef DIAGNOSTIC
		if (m->m_type != MT_SONAME)
			panic("receive 1a");
#endif
		orig_resid = 0;
		if (flags & MSG_PEEK) {
			m = m->m_next;
		} else {
			sbfree(&so->so_rcv, m);
			MFREE(m, so->so_rcv.sb_mb);
			m = so->so_rcv.sb_mb;
		}
	}
	while (m && m->m_type == MT_CONTROL && error == 0) {
		if (flags & MSG_PEEK) {
			m = m->m_next;
		} else {
			sbfree(&so->so_rcv, m);
			MFREE(m, so->so_rcv.sb_mb);
			m = so->so_rcv.sb_mb;
		}
	}

	/*
	 * If m is non-NULL, we have some data to read.  From now on,
	 * make sure to keep sb_lastrecord consistent when working on
	 * the last packet on the chain (nextrecord == NULL) and we
	 * change m->m_nextpkt.
	 */
	if (m) {
		if ((flags & MSG_PEEK) == 0) {
			m->m_nextpkt = nextrecord;
			/*
			 * If nextrecord == NULL (this is a single chain),
			 * then sb_lastrecord may not be valid here if m
			 * was changed earlier.
			 */
			if (nextrecord == NULL) {
				KASSERT(so->so_rcv.sb_mb == m);
				so->so_rcv.sb_lastrecord = m;
			}
		}
		type = m->m_type;
		if (type == MT_OOBDATA)
			flags |= MSG_OOB;
	} else {
		if ((flags & MSG_PEEK) == 0) {
			KASSERT(so->so_rcv.sb_mb == m);
			so->so_rcv.sb_mb = nextrecord;
			SB_EMPTY_FIXUP(&so->so_rcv);
		}
	}
	SBLASTRECORDCHK(&so->so_rcv, "kttcp_soreceive 2");
	SBLASTMBUFCHK(&so->so_rcv, "kttcp_soreceive 2");

	moff = 0;
	offset = 0;
	while (m && resid > 0 && error == 0) {
		if (m->m_type == MT_OOBDATA) {
			if (type != MT_OOBDATA)
				break;
		} else if (type == MT_OOBDATA)
			break;
#ifdef DIAGNOSTIC
		else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
			panic("receive 3");
#endif
		so->so_state &= ~SS_RCVATMARK;
		len = resid;
		if (so->so_oobmark && len > so->so_oobmark - offset)
			len = so->so_oobmark - offset;
		if (len > m->m_len - moff)
			len = m->m_len - moff;
		/*
		 * If mp is set, just pass back the mbufs.
		 * Otherwise copy them out via the uio, then free.
		 * Sockbuf must be consistent here (points to current mbuf,
		 * it points to next record) when we drop priority;
		 * we must note any additions to the sockbuf when we
		 * block interrupts again.
		 */
		resid -= len;
		if (len == m->m_len - moff) {
			if (m->m_flags & M_EOR)
				flags |= MSG_EOR;
			if (flags & MSG_PEEK) {
				m = m->m_next;
				moff = 0;
			} else {
				nextrecord = m->m_nextpkt;
				sbfree(&so->so_rcv, m);
				if (mp) {
					*mp = m;
					mp = &m->m_next;
					so->so_rcv.sb_mb = m = m->m_next;
					*mp = NULL;
				} else {
					MFREE(m, so->so_rcv.sb_mb);
					m = so->so_rcv.sb_mb;
				}
				/*
				 * If m != NULL, we also know that
				 * so->so_rcv.sb_mb != NULL.
				 */
				KASSERT(so->so_rcv.sb_mb == m);
				if (m) {
					m->m_nextpkt = nextrecord;
					if (nextrecord == NULL)
						so->so_rcv.sb_lastrecord = m;
				} else {
					so->so_rcv.sb_mb = nextrecord;
					SB_EMPTY_FIXUP(&so->so_rcv);
				}
				SBLASTRECORDCHK(&so->so_rcv,
				    "kttcp_soreceive 3");
				SBLASTMBUFCHK(&so->so_rcv,
				    "kttcp_soreceive 3");
			}
		} else {
			if (flags & MSG_PEEK)
				moff += len;
			else {
				if (mp) {
					sounlock(so);
					*mp = m_copym(m, 0, len, M_WAIT);
					solock(so);
				}
				m->m_data += len;
				m->m_len -= len;
				so->so_rcv.sb_cc -= len;
			}
		}
		if (so->so_oobmark) {
			if ((flags & MSG_PEEK) == 0) {
				so->so_oobmark -= len;
				if (so->so_oobmark == 0) {
					so->so_state |= SS_RCVATMARK;
					break;
				}
			} else {
				offset += len;
				if (offset == so->so_oobmark)
					break;
			}
		}
		if (flags & MSG_EOR)
			break;
		/*
		 * If the MSG_WAITALL flag is set (for non-atomic socket),
		 * we must not quit until "uio->uio_resid == 0" or an error
		 * termination.  If a signal/timeout occurs, return
		 * with a short count but without error.
		 * Keep sockbuf locked against other readers.
		 */
		while (flags & MSG_WAITALL && m == NULL && resid > 0 &&
		    !sosendallatonce(so) && !nextrecord) {
			if (so->so_error || so->so_state & SS_CANTRCVMORE)
				break;
			/*
			 * If we are peeking and the socket receive buffer is
			 * full, stop since we can't get more data to peek at.
			 */
			if ((flags & MSG_PEEK) && sbspace(&so->so_rcv) <= 0)
				break;
			/*
			 * If we've drained the socket buffer, tell the
			 * protocol in case it needs to do something to
			 * get it filled again.
			 */
			if ((pr->pr_flags & PR_WANTRCVD) && so->so_pcb) {
				(*pr->pr_usrreqs->pr_rcvd)(so, flags, l);
			}
			SBLASTRECORDCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 2");
			SBLASTMBUFCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 2");
			error = sbwait(&so->so_rcv);
			if (error) {
				sbunlock(&so->so_rcv);
				sounlock(so);
				return (0);
			}
			if ((m = so->so_rcv.sb_mb) != NULL)
				nextrecord = m->m_nextpkt;
		}
	}

	if (m && pr->pr_flags & PR_ATOMIC) {
		flags |= MSG_TRUNC;
		if ((flags & MSG_PEEK) == 0)
			(void) sbdroprecord(&so->so_rcv);
	}
	if ((flags & MSG_PEEK) == 0) {
		if (m == NULL) {
			/*
			 * First part is an SB_EMPTY_FIXUP().  Second part
			 * makes sure sb_lastrecord is up-to-date if
			 * there is still data in the socket buffer.
			 */
			so->so_rcv.sb_mb = nextrecord;
			if (so->so_rcv.sb_mb == NULL) {
				so->so_rcv.sb_mbtail = NULL;
				so->so_rcv.sb_lastrecord = NULL;
			} else if (nextrecord->m_nextpkt == NULL)
				so->so_rcv.sb_lastrecord = nextrecord;
		}
		SBLASTRECORDCHK(&so->so_rcv, "kttcp_soreceive 4");
		SBLASTMBUFCHK(&so->so_rcv, "kttcp_soreceive 4");
		if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) {
			(*pr->pr_usrreqs->pr_rcvd)(so, flags, l);
		}
	}
	if (orig_resid == resid && orig_resid &&
	    (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
		sbunlock(&so->so_rcv);
		goto restart;
	}

	if (flagsp)
		*flagsp |= flags;
 release:
	sbunlock(&so->so_rcv);
	sounlock(so);
	*done = slen - resid;
#if 0
	printf("soreceive: error %d slen %llu resid %lld\n", error, slen, resid);
#endif
	return (error);
}
Example #6
0
static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr preq_addr;
    int dhcp_msg_type, val;
    uint8_t *q;
    uint8_t *end;
    uint8_t client_ethaddr[ETH_ALEN];

    /* extract exact DHCP msg type */
    dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
    DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
    if (preq_addr.s_addr != htonl(0L))
        DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
    else {
        DPRINTF("\n");
    }

    if (dhcp_msg_type == 0)
        dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */

    if (dhcp_msg_type != DHCPDISCOVER &&
        dhcp_msg_type != DHCPREQUEST)
        return;

    /* Get client's hardware address from bootp request */
    memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN);

    m = m_get(slirp);
    if (!m) {
        return;
    }
    m->m_data += IF_MAXLINKHDR;
    rbp = (struct bootp_t *)m->m_data;
    m->m_data += sizeof(struct udpiphdr);
    memset(rbp, 0, sizeof(struct bootp_t));

    if (dhcp_msg_type == DHCPDISCOVER) {
        if (preq_addr.s_addr != htonl(0L)) {
            bc = request_addr(slirp, &preq_addr, client_ethaddr);
            if (bc) {
                daddr.sin_addr = preq_addr;
            }
        }
        if (!bc) {
         new_addr:
            bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr);
            if (!bc) {
                DPRINTF("no address left\n");
                return;
            }
        }
        memcpy(bc->macaddr, client_ethaddr, ETH_ALEN);
    } else if (preq_addr.s_addr != htonl(0L)) {
        bc = request_addr(slirp, &preq_addr, client_ethaddr);
        if (bc) {
            daddr.sin_addr = preq_addr;
            memcpy(bc->macaddr, client_ethaddr, ETH_ALEN);
        } else {
            /* DHCPNAKs should be sent to broadcast */
            daddr.sin_addr.s_addr = 0xffffffff;
        }
    } else {
        bc = find_addr(slirp, &daddr.sin_addr, bp->bp_hwaddr);
        if (!bc) {
            /* if never assigned, behaves as if it was already
               assigned (windows fix because it remembers its address) */
            goto new_addr;
        }
    }

    /* Update ARP table for this IP address */
    arp_table_add(slirp, daddr.sin_addr.s_addr, client_ethaddr);

    saddr.sin_addr = slirp->vhost_addr;
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    rbp->bp_op = BOOTP_REPLY;
    rbp->bp_xid = bp->bp_xid;
    rbp->bp_htype = 1;
    rbp->bp_hlen = 6;
    memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, ETH_ALEN);

    rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

    q = rbp->bp_vend;
    end = (uint8_t *)&rbp[1];
    memcpy(q, rfc1533_cookie, 4);
    q += 4;

    if (bc) {
        DPRINTF("%s addr=%08" PRIx32 "\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                ntohl(daddr.sin_addr.s_addr));

        if (dhcp_msg_type == DHCPDISCOVER) {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPOFFER;
        } else /* DHCPREQUEST */ {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPACK;
        }

        if (slirp->bootp_filename)
            snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
                     slirp->bootp_filename);

        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        memcpy(q, &slirp->vnetwork_mask, 4);
        q += 4;

        if (!slirp->restricted) {
            *q++ = RFC1533_GATEWAY;
            *q++ = 4;
            memcpy(q, &saddr.sin_addr, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            memcpy(q, &slirp->vnameserver_addr, 4);
            q += 4;
        }

        *q++ = RFC2132_LEASE_TIME;
        *q++ = 4;
        val = htonl(LEASE_TIME);
        memcpy(q, &val, 4);
        q += 4;

        if (*slirp->client_hostname) {
            val = strlen(slirp->client_hostname);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting host name option.");
            } else {
                *q++ = RFC1533_HOSTNAME;
                *q++ = val;
                memcpy(q, slirp->client_hostname, val);
                q += val;
            }
        }

        if (slirp->vdomainname) {
            val = strlen(slirp->vdomainname);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting domain name option.");
            } else {
                *q++ = RFC1533_DOMAINNAME;
                *q++ = val;
                memcpy(q, slirp->vdomainname, val);
                q += val;
            }
        }

        if (slirp->tftp_server_name) {
            val = strlen(slirp->tftp_server_name);
            if (q + val + 2 >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting tftp-server-name option.");
            } else {
                *q++ = RFC2132_TFTP_SERVER_NAME;
                *q++ = val;
                memcpy(q, slirp->tftp_server_name, val);
                q += val;
            }
        }

        if (slirp->vdnssearch) {
            val = slirp->vdnssearch_len;
            if (q + val >= end) {
                g_warning("DHCP packet size exceeded, "
                    "omitting domain-search option.");
            } else {
                memcpy(q, slirp->vdnssearch, val);
                q += val;
            }
        }
    } else {
        static const char nak_msg[] = "requested address not available";

        DPRINTF("nak'ed addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));

        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPNAK;

        *q++ = RFC2132_MESSAGE;
        *q++ = sizeof(nak_msg) - 1;
        memcpy(q, nak_msg, sizeof(nak_msg) - 1);
        q += sizeof(nak_msg) - 1;
    }
    assert(q < end);
    *q = RFC1533_END;

    daddr.sin_addr.s_addr = 0xffffffffu;

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Example #7
0
MAT *MGVF(MAT *I, double vx, double vy) {
	/*
	% MGVF calculate the motion gradient vector flow (MGVF) 
	%  for the image 'I'
	%
	% Based on the algorithm in:
	%  Motion gradient vector flow: an external force for tracking rolling 
	%   leukocytes with shape and size constrained active contours
	%  Ray, N. and Acton, S.T.
	%  IEEE Transactions on Medical Imaging
	%  Volume: 23, Issue: 12, December 2004 
	%  Pages: 1466 - 1478
	%
	% INPUTS
	%   I...........image
	%   vx,vy.......velocity vector
	%   
	% OUTPUT
	%   IMGVF.......MGVF vector field as image
	%
	% Matlab code written by: DREW GILLIAM (based on work by GANG DONG /
	%                                                        NILANJAN RAY)
	% Ported to C by: MICHAEL BOYER
	*/

	// Constants
	double converge = 0.00001;
	double mu = 0.5;
	double epsilon = 0.0000000001;
	double lambda = 8.0 * mu + 1.0;
	// Smallest positive value expressable in double-precision
	double eps = pow(2.0, -52.0);
	// Maximum number of iterations to compute the MGVF matrix
	int iterations = 500;
	
	// Find the maximum and minimum values in I
	int m = I->m, n = I->n, i, j;
	double Imax = m_get_val(I, 0, 0);
	double Imin = m_get_val(I, 0, 0);
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			double temp = m_get_val(I, i, j);
			if (temp > Imax) Imax = temp;
			else if (temp < Imin) Imin = temp;
		}
	}
	
	// Normalize the image I
	double scale = 1.0 / (Imax - Imin + eps);
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			double old_val = m_get_val(I, i, j);
			m_set_val(I, i, j, (old_val - Imin) * scale);
		}
	}

	// Initialize the output matrix IMGVF with values from I
	MAT *IMGVF = m_get(m, n);
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			m_set_val(IMGVF, i, j, m_get_val(I, i, j));
		}
	}
	
	// Precompute row and column indices for the
	//  neighbor difference computation below
	int *rowU = (int *) malloc(sizeof(int) * m);
	int *rowD = (int *) malloc(sizeof(int) * m);
	int *colL = (int *) malloc(sizeof(int) * n);
	int *colR = (int *) malloc(sizeof(int) * n);
	rowU[0] = 0;
	rowD[m - 1] = m - 1;
	for (i = 1; i < m; i++) {
		rowU[i] = i - 1;
		rowD[i - 1] = i;
	}
	colL[0] = 0;
	colR[n - 1] = n - 1;
	for (j = 1; j < n; j++) {
		colL[j] = j - 1;
		colR[j - 1] = j;
	}
	
	// Allocate matrices used in the while loop below
	MAT *U    = m_get(m, n), *D    = m_get(m, n), *L    = m_get(m, n), *R    = m_get(m, n);
	MAT *UR   = m_get(m, n), *DR   = m_get(m, n), *UL   = m_get(m, n), *DL   = m_get(m, n);
	MAT *UHe  = m_get(m, n), *DHe  = m_get(m, n), *LHe  = m_get(m, n), *RHe  = m_get(m, n);
	MAT *URHe = m_get(m, n), *DRHe = m_get(m, n), *ULHe = m_get(m, n), *DLHe = m_get(m, n);

	
	// Precompute constants to avoid division in the for loops below
	double mu_over_lambda = mu / lambda;
	double one_over_lambda = 1.0 / lambda;
	
	// Compute the MGVF
	int iter = 0;
	double mean_diff = 1.0;
	while ((iter < iterations) && (mean_diff > converge)) { 
	    
	    // Compute the difference between each pixel and its eight neighbors
		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				double subtrahend = m_get_val(IMGVF, i, j);
				m_set_val(U, i, j, m_get_val(IMGVF, rowU[i], j) - subtrahend);
				m_set_val(D, i, j, m_get_val(IMGVF, rowD[i], j) - subtrahend);
				m_set_val(L, i, j, m_get_val(IMGVF, i, colL[j]) - subtrahend);
				m_set_val(R, i, j, m_get_val(IMGVF, i, colR[j]) - subtrahend);
				m_set_val(UR, i, j, m_get_val(IMGVF, rowU[i], colR[j]) - subtrahend);
				m_set_val(DR, i, j, m_get_val(IMGVF, rowD[i], colR[j]) - subtrahend);
				m_set_val(UL, i, j, m_get_val(IMGVF, rowU[i], colL[j]) - subtrahend);
				m_set_val(DL, i, j, m_get_val(IMGVF, rowD[i], colL[j]) - subtrahend);
			}
		}
		
	    // Compute the regularized heaviside version of the matrices above
		heaviside( UHe,  U, -vy,      epsilon);
		heaviside( DHe,  D,  vy,      epsilon);
		heaviside( LHe,  L, -vx,      epsilon);
		heaviside( RHe,  R,  vx,      epsilon);
		heaviside(URHe, UR,  vx - vy, epsilon);
		heaviside(DRHe, DR,  vx + vy, epsilon);
		heaviside(ULHe, UL, -vx - vy, epsilon);
		heaviside(DLHe, DL,  vy - vx, epsilon);
		
		// Update the IMGVF matrix
		double total_diff = 0.0;
		for (i = 0; i < m; i++) {
			for (j = 0; j < n; j++) {
				// Store the old value so we can compute the difference later
				double old_val = m_get_val(IMGVF, i, j);
				
				// Compute IMGVF += (mu / lambda)(UHe .*U  + DHe .*D  + LHe .*L  + RHe .*R +
				//                                URHe.*UR + DRHe.*DR + ULHe.*UL + DLHe.*DL);
				double vU  = m_get_val(UHe,  i, j) * m_get_val(U,  i, j);
				double vD  = m_get_val(DHe,  i, j) * m_get_val(D,  i, j);
				double vL  = m_get_val(LHe,  i, j) * m_get_val(L,  i, j);
				double vR  = m_get_val(RHe,  i, j) * m_get_val(R,  i, j);
				double vUR = m_get_val(URHe, i, j) * m_get_val(UR, i, j);
				double vDR = m_get_val(DRHe, i, j) * m_get_val(DR, i, j);
				double vUL = m_get_val(ULHe, i, j) * m_get_val(UL, i, j);
				double vDL = m_get_val(DLHe, i, j) * m_get_val(DL, i, j);				
				double vHe = old_val + mu_over_lambda * (vU + vD + vL + vR + vUR + vDR + vUL + vDL);
				
				// Compute IMGVF -= (1 / lambda)(I .* (IMGVF - I))
				double vI = m_get_val(I, i, j);
				double new_val = vHe - (one_over_lambda * vI * (vHe - vI));
				m_set_val(IMGVF, i, j, new_val);
				
				// Keep track of the absolute value of the differences
				//  between this iteration and the previous one
				total_diff += fabs(new_val - old_val);
			}
		}
		
		// Compute the mean absolute difference between this iteration
		//  and the previous one to check for convergence
		mean_diff = total_diff / (double) (m * n);
	    
		iter++;
	}
	
	// Free memory
	free(rowU); free(rowD); free(colL); free(colR);
	m_free(U);    m_free(D);    m_free(L);    m_free(R);
	m_free(UR);   m_free(DR);   m_free(UL);   m_free(DL);
	m_free(UHe);  m_free(DHe);  m_free(LHe);  m_free(RHe);
	m_free(URHe); m_free(DRHe); m_free(ULHe); m_free(DLHe);

	return IMGVF;
}
Example #8
0
/*
 * Send NDP Router Advertisement
 */
void ndp_send_ra(Slirp *slirp)
{
    DEBUG_CALL("ndp_send_ra");

    /* Build IPv6 packet */
    struct mbuf *t = m_get(slirp);
    struct ip6 *rip = mtod(t, struct ip6 *);
    size_t pl_size = 0;
    struct in6_addr addr;
    uint32_t scope_id;

    rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
    rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
    rip->ip_nh = IPPROTO_ICMPV6;

    /* Build ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = ICMP6_NDP_RA;
    ricmp->icmp6_code = 0;
    ricmp->icmp6_cksum = 0;

    /* NDP */
    ricmp->icmp6_nra.chl = NDP_AdvCurHopLimit;
    ricmp->icmp6_nra.M = NDP_AdvManagedFlag;
    ricmp->icmp6_nra.O = NDP_AdvOtherConfigFlag;
    ricmp->icmp6_nra.reserved = 0;
    ricmp->icmp6_nra.lifetime = htons(NDP_AdvDefaultLifetime);
    ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime);
    ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime);
    t->m_data += ICMP6_NDP_RA_MINLEN;
    pl_size += ICMP6_NDP_RA_MINLEN;

    /* Source link-layer address (NDP option) */
    struct ndpopt *opt = mtod(t, struct ndpopt *);
    opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
    opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
    in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer);
    t->m_data += NDPOPT_LINKLAYER_LEN;
    pl_size += NDPOPT_LINKLAYER_LEN;

    /* Prefix information (NDP option) */
    struct ndpopt *opt2 = mtod(t, struct ndpopt *);
    opt2->ndpopt_type = NDPOPT_PREFIX_INFO;
    opt2->ndpopt_len = NDPOPT_PREFIXINFO_LEN / 8;
    opt2->ndpopt_prefixinfo.prefix_length = slirp->vprefix_len;
    opt2->ndpopt_prefixinfo.L = 1;
    opt2->ndpopt_prefixinfo.A = 1;
    opt2->ndpopt_prefixinfo.reserved1 = 0;
    opt2->ndpopt_prefixinfo.valid_lt = htonl(NDP_AdvValidLifetime);
    opt2->ndpopt_prefixinfo.pref_lt = htonl(NDP_AdvPrefLifetime);
    opt2->ndpopt_prefixinfo.reserved2 = 0;
    opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6;
    t->m_data += NDPOPT_PREFIXINFO_LEN;
    pl_size += NDPOPT_PREFIXINFO_LEN;

    /* Prefix information (NDP option) */
    if (get_dns6_addr(&addr, &scope_id) >= 0) {
        /* Host system does have an IPv6 DNS server, announce our proxy.  */
        struct ndpopt *opt3 = mtod(t, struct ndpopt *);
        opt3->ndpopt_type = NDPOPT_RDNSS;
        opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
        opt3->ndpopt_rdnss.reserved = 0;
        opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
        opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
        t->m_data += NDPOPT_RDNSS_LEN;
        pl_size += NDPOPT_RDNSS_LEN;
    }

    rip->ip_pl = htons(pl_size);
    t->m_data -= sizeof(struct ip6) + pl_size;
    t->m_len = sizeof(struct ip6) + pl_size;

    /* ICMPv6 Checksum */
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}
Example #9
0
/*
 * Initialize the aurp pipe -
 * -Create, initialize, and start the aurpd kernel process; we need
 *  a process to permit queueing between the socket and the stream,
 *  which is necessary for orderly access to the socket structure.
 * -The user process (aurpd) is there to 'build' the AURP
 *  stream, act as a 'logging agent' (:-}), and hold open the stream
 *  during its use.
 * -Data and AURP packets from the DDP stream will be fed into the
 *  UDP tunnel (AURPsend())
 * -Data and AURP packets from the UDP tunnel will be fed into the
 *  DDP stream (ip_to_atalk(), via the kernel process).
 */
int
aurpd_start()
{
	register int error;
	register struct socket *so;
	struct mbuf *m;
	int maxbuf;
	struct sockopt sopt;

	if (suser(current_proc()->p_ucred, &current_proc()->p_acflag) != 0 )
		return(EPERM);

	/*
	 * Set up state prior to starting kernel process so we can back out
	 *  (error return) if something goes wrong.
	 */
	bzero((char *)&aurp_global.tunnel, sizeof(aurp_global.tunnel));
	/*lock_alloc(&aurp_global.glock, LOCK_ALLOC_PIN, AURP_EVNT_LOCK, -1);*/
	ATLOCKINIT(aurp_global.glock);
	ATEVENTINIT(aurp_global.event_anchor);

	/* open udp socket */
	if (aurp_global.udp_port == 0)
		aurp_global.udp_port = AURP_SOCKNUM;
	error = socreate(AF_INET, &aurp_global.tunnel, SOCK_DGRAM,
			 IPPROTO_UDP);
	if (error)
	{	dPrintf(D_M_AURP, D_L_FATAL, ("AURP: Can't get socket (%d)\n",
			error));
		return(error);
	}

	so = aurp_global.tunnel;

	if ((error = aurp_bindrp(so)) != 0)
	{	dPrintf(D_M_AURP, D_L_FATAL,
			("AURP: Can't bind to port %d (error %d)\n",
			aurp_global.udp_port, error));
		soclose(so);
		return(error);
	}

	sblock(&so->so_rcv, M_WAIT);
	sblock(&so->so_snd, M_WAIT);

	/*
	 * Set socket Receive buffer size
	 */
	m = m_get(M_WAIT, MT_SOOPTS);
	if (m == NULL) {
		error = ENOBUFS;
		goto out;
	} else {
		maxbuf = M_RCVBUF;
		sopt.sopt_val     = &maxbuf;
		sopt.sopt_valsize = sizeof(maxbuf);
		sopt.sopt_level   = SOL_SOCKET;
		sopt.sopt_name    = SO_RCVBUF;
		sopt.sopt_dir     = SOPT_SET;
		sopt.sopt_p		  = NULL;
		if ((error = sosetopt(so, &sopt)) != 0)
			goto out;
	}

	/*
	 * Set socket Send buffer size
	 */
	m = m_get(M_WAIT, MT_SOOPTS);
	if (m == NULL) {
		error = ENOBUFS;
		goto out;
	} else {

		maxbuf = M_SNDBUF;
		sopt.sopt_val     = &maxbuf;
		sopt.sopt_valsize = sizeof(maxbuf);
		sopt.sopt_level   = SOL_SOCKET;
		sopt.sopt_name    = SO_SNDBUF;
		sopt.sopt_dir     = SOPT_SET;
		sopt.sopt_p		  = NULL;
		if ((error = sosetopt(so, &sopt)) != 0)
			goto out;
	}

	so->so_upcall = aurp_wakeup;
	so->so_upcallarg = (caddr_t)AE_UDPIP; /* Yuck */
	so->so_state |= SS_NBIO;
	so->so_rcv.sb_flags |=(SB_SEL|SB_NOINTR);
	so->so_snd.sb_flags |=(SB_SEL|SB_NOINTR);

out:
	sbunlock(&so->so_snd);
	sbunlock(&so->so_rcv);

	return(error);
}
Example #10
0
File: vario.c Project: cran/gstat
void check_variography(const VARIOGRAM **v, int n_vars)
/*
 * check for intrinsic correlation, linear model of coregionalisation
 * or else (with warning) Cauchy Swartz
 */
{
	int i, j, k, ic = 0, lmc, posdef = 1;
	MAT **a = NULL;
	double b;
	char *reason = NULL;

	if (n_vars <= 1)
		return;
/* 
 * find out if lmc (linear model of coregionalization) hold: 
 * all models must have equal base models (sequence and range)
 */
	for (i = 1, lmc = 1; lmc && i < get_n_vgms(); i++) {
		if (v[0]->n_models != v[i]->n_models) {
			reason = "number of models differ";
			lmc = 0;
		}
		for (k = 0; lmc && k < v[0]->n_models; k++) {
			if (v[0]->part[k].model != v[i]->part[k].model) {
				reason = "model types differ";
				lmc = 0;
			}
			if (v[0]->part[k].range[0] != v[i]->part[k].range[0]) {
				reason = "ranges differ";
				lmc = 0;
			}
		}
		for (k = 0; lmc && k < v[0]->n_models; k++)
			if (v[0]->part[k].tm_range != NULL) {
				if (v[i]->part[k].tm_range == NULL) {
					reason = "anisotropy for part of models";
					lmc = 0;
				} else if (
		v[0]->part[k].tm_range->ratio[0] != v[i]->part[k].tm_range->ratio[0] ||
		v[0]->part[k].tm_range->ratio[1] != v[i]->part[k].tm_range->ratio[1] ||
		v[0]->part[k].tm_range->angle[0] != v[i]->part[k].tm_range->angle[0] ||
		v[0]->part[k].tm_range->angle[1] != v[i]->part[k].tm_range->angle[1] ||
		v[0]->part[k].tm_range->angle[2] != v[i]->part[k].tm_range->angle[2]
				) {
					reason = "anisotropy parameters are not equal";
					lmc = 0;
				}
			} else if (v[i]->part[k].tm_range != NULL) {
				reason = "anisotropy for part of models";
				lmc = 0;
			}
	}
	if (lmc) {
/*
 * check for ic:
 */
		a = (MAT **) emalloc(v[0]->n_models * sizeof(MAT *));
		for (k = 0; k < v[0]->n_models; k++)
			a[k] = m_get(n_vars, n_vars);
		for (i = 0; i < n_vars; i++) {
			for (j = 0; j < n_vars; j++) { /* for all variogram triplets: */
				for (k = 0; k < v[0]->n_models; k++)
					ME(a[k], i, j) = v[LTI(i,j)]->part[k].sill;
			}
		}
		/* for ic: a's must be scaled versions of each other: */
		ic = 1;
		for (k = 1, ic = 1; ic && k < v[0]->n_models; k++) {
			b = ME(a[0], 0, 0)/ME(a[k], 0, 0);
			for (i = 0; ic && i < n_vars; i++)
				for (j = 0; ic && j < n_vars; j++)
					if (fabs(ME(a[0], i, j) / ME(a[k], i, j) - b) > EPSILON)
						ic = 0;	
		}
		/* check posdef matrices */
		for (i = 0, lmc = 1, posdef = 1; i < v[0]->n_models; i++) {
			posdef = is_posdef(a[i]);
			if (posdef == 0) {
				reason = "coefficient matrix not positive definite";
				if (DEBUG_COV) {
					printlog("non-positive definite coefficient matrix %d:\n", 
						i);
					m_logoutput(a[i]);
				}
				ic = lmc = 0;
			}
			if (! posdef)
				printlog(
				"non-positive definite coefficient matrix in structure %d", 
				i+1);
		}
		for (k = 0; k < v[0]->n_models; k++)
			m_free(a[k]);
		efree(a);

		if (ic) {
			printlog("Intrinsic Correlation found. Good.\n");
			return;
		} else if (lmc) {
			printlog("Linear Model of Coregionalization found. Good.\n");
			return;
		}
	}
/*
 * lmc does not hold: check on Cauchy Swartz
 */
	pr_warning("No Intrinsic Correlation or Linear Model of Coregionalization found\nReason: %s", reason ? reason : "unknown");
	if (gl_nocheck == 0) {
		pr_warning("[add `set = list(nocheck = 1)' to the gstat() or krige() to ignore the following error]\n");
		ErrMsg(ER_IMPOSVAL, "variograms do not satisfy a legal model");
	}
	printlog("Now checking for Cauchy-Schwartz inequalities:\n");
	for (i = 0; i < n_vars; i++)
		for (j = 0; j < i; j++)
			if (is_valid_cs(v[LTI(i,i)], v[LTI(j,j)], v[LTI(i,j)])) {
				printlog("variogram(%s,%s) passed Cauchy-Schwartz\n",
					name_identifier(j), name_identifier(i));
			} else
				pr_warning("Cauchy-Schwartz inequality found for variogram(%s,%s)",
						name_identifier(j), name_identifier(i) );
	return;
}
Example #11
0
/*
 * Take incoming datagram fragment and try to
 * reassemble it into whole datagram.  If a chain for
 * reassembly of this datagram already exists, then it
 * is given as fp; otherwise have to make a chain.
 */
struct ip *ip_reass(struct ipasfrag *ip, struct ipq *fp)
{
	struct mbuf *m = dtom(ip);
	struct ipasfrag *q;
	int hlen = ip->ip_hl << 2;
	int i, next;
	
	DEBUG_CALL("ip_reass");
	DEBUG_ARG("ip = %lx", (long)ip);
	DEBUG_ARG("fp = %lx", (long)fp);
	DEBUG_ARG("m = %lx", (long)m);

	/*
	 * Presence of header sizes in mbufs
	 * would confuse code below.
         * Fragment m_data is concatenated.
	 */
	m->m_data += hlen;
	m->m_len -= hlen;

	/*
	 * If first fragment to arrive, create a reassembly queue.
	 */
	if (fp == 0) {
	  struct mbuf *t;
	  if ((t = m_get()) == NULL) goto dropfrag;
	  fp = mtod(t, struct ipq *);
	  insque_32(fp, &ipq);
	  fp->ipq_ttl = IPFRAGTTL;
	  fp->ipq_p = ip->ip_p;
	  fp->ipq_id = ip->ip_id;
	  fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
	  fp->ipq_src = ((struct ip *)ip)->ip_src;
	  fp->ipq_dst = ((struct ip *)ip)->ip_dst;
	  q = (struct ipasfrag *)fp;
	  goto insert;
	}
	
	/*
	 * Find a segment which begins after this one does.
	 */
	for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
	    q = (struct ipasfrag *)q->ipf_next)
		if (q->ip_off > ip->ip_off)
			break;

	/*
	 * If there is a preceding segment, it may provide some of
	 * our data already.  If so, drop the data from the incoming
	 * segment.  If it provides all of our data, drop us.
	 */
	if (q->ipf_prev != (ipasfragp_32)fp) {
		i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
		  ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
		if (i > 0) {
			if (i >= ip->ip_len)
				goto dropfrag;
			m_adj(dtom(ip), i);
			ip->ip_off += i;
			ip->ip_len -= i;
		}
	}

	/*
	 * While we overlap succeeding segments trim them or,
	 * if they are completely covered, dequeue them.
	 */
	while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
		i = (ip->ip_off + ip->ip_len) - q->ip_off;
		if (i < q->ip_len) {
			q->ip_len -= i;
			q->ip_off += i;
			m_adj(dtom(q), i);
			break;
		}
		q = (struct ipasfrag *) q->ipf_next;
		m_freem(dtom((struct ipasfrag *) q->ipf_prev));
		ip_deq((struct ipasfrag *) q->ipf_prev);
	}

insert:
	/*
	 * Stick new segment in its place;
	 * check for complete reassembly.
	 */
	ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
	next = 0;
	for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
	     q = (struct ipasfrag *) q->ipf_next) {
		if (q->ip_off != next)
			return (0);
		next += q->ip_len;
	}
	if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
		return (0);

	/*
	 * Reassembly is complete; concatenate fragments.
	 */
	q = (struct ipasfrag *) fp->ipq_next;
	m = dtom(q);

	q = (struct ipasfrag *) q->ipf_next;
	while (q != (struct ipasfrag *)fp) {
	  struct mbuf *t;
	  t = dtom(q);
	  q = (struct ipasfrag *) q->ipf_next;
	  m_cat(m, t);
	}

	/*
	 * Create header for new ip packet by
	 * modifying header of first packet;
	 * dequeue and discard fragment reassembly header.
	 * Make header visible.
	 */
	ip = (struct ipasfrag *) fp->ipq_next;

	/*
	 * If the fragments concatenated to an mbuf that's
	 * bigger than the total size of the fragment, then and
	 * m_ext buffer was alloced. But fp->ipq_next points to
	 * the old buffer (in the mbuf), so we must point ip
	 * into the new buffer.
	 */
	if (m->m_flags & M_EXT) {
	  int delta;
	  delta = (char *)ip - m->m_dat;
	  ip = (struct ipasfrag *)(m->m_ext + delta);
	}

	/* DEBUG_ARG("ip = %lx", (long)ip); 
	 * ip=(struct ipasfrag *)m->m_data; */

	ip->ip_len = next;
	ip->ipf_mff &= ~1;
	((struct ip *)ip)->ip_src = fp->ipq_src;
	((struct ip *)ip)->ip_dst = fp->ipq_dst;
	remque_32(fp);
	(void) m_free(dtom(fp));
	m = dtom(ip);
	m->m_len += (ip->ip_hl << 2);
	m->m_data -= (ip->ip_hl << 2);

	return ((struct ip *)ip);

dropfrag:
	ipstat.ips_fragdropped++;
	m_freem(m);
	return (0);
}
Example #12
0
bool VecSliderMenuItem::OnKey(int key, int mod) 
{

	float inc = m_scale * kInc;
	if(mod & KMOD_SHIFT) inc = m_scale * kLargeInc;
	else if(mod & KMOD_CTRL) inc = m_scale * kSmallInc;

	float incAmt = 0.f;
	switch(key)
	{
		case SDLK_UP:
			m_pos = Max(0, m_pos - 1);
			break;
		case SDLK_DOWN:
			m_pos = Min(VECSLIDE_NUM-1, m_pos + 1);
			break;
		case SDLK_LEFT:
			incAmt = -inc;
			break;
		case SDLK_RIGHT:
			incAmt = inc;
			break;
		case SDLK_BACKSPACE:
			menu_DeactivateMenuItem();
			break;
		default:
			break;
	}

	vec3 val = m_get();
	vec3 old = val;
	float radAmt = (M_PI / 180.f) * incAmt;
	mat4 rotmat;
	static const vec3 kXAxis = {1,0,0};
	static const vec3 kYAxis = {0,1,0};
	static const vec3 kZAxis = {0,0,1};
	switch(m_pos)
	{
		case VECSLIDE_RotateX:
			rotmat = RotateAround(kXAxis, radAmt);
			val = TransformVec(rotmat, val);
			break;
		case VECSLIDE_RotateY:
			rotmat = RotateAround(kYAxis, radAmt);
			val = TransformVec(rotmat, val);
			break;
		case VECSLIDE_RotateZ:
			rotmat = RotateAround(kZAxis, radAmt);
			val = TransformVec(rotmat, val);
			break;
		case VECSLIDE_X:
			val.x += incAmt;
			break;
		case VECSLIDE_Y:
			val.y += incAmt;
			break;
		case VECSLIDE_Z:
			val.z += incAmt;
			break;
		case VECSLIDE_Length:
			{
				float len = Length(val);
				val = val * (len+incAmt) / len;
			}
			break;
		default:break;
	}
	vec3 newVal = m_limits(val);
	if(newVal != old)
	{
		m_set(newVal);
		UpdateData();
	}
	return true;
}
Example #13
0
/*
 * IP output.  The packet in mbuf chain m contains a skeletal IP
 * header (with len, off, ttl, proto, tos, src, dst).
 * The mbuf chain containing the packet will be freed.
 * The mbuf opt, if present, will not be freed.
 */
int
ip_output(struct socket *so, struct mbuf *m0)
{
	register struct ip *ip;
	register struct mbuf *m = m0;
	register int hlen = sizeof(struct ip );
	int len, off, error = 0;

	DEBUG_CALL("ip_output");
	DEBUG_ARG("so = %lx", (long)so);
	DEBUG_ARG("m0 = %lx", (long)m0);

	/* We do no options */
/*	if (opt) {
 *		m = ip_insertoptions(m, opt, &len);
 *		hlen = len;
 *	}
 */
	ip = mtod(m, struct ip *);
	/*
	 * Fill in IP header.
	 */
	ip->ip_v = IPVERSION;
	ip->ip_off &= IP_DF;
	ip->ip_id = htons(ip_id++);
	ip->ip_hl = hlen >> 2;
	STAT(ipstat.ips_localout++);

	/*
	 * Verify that we have any chance at all of being able to queue
	 *      the packet or packet fragments
	 */
	/* XXX Hmmm... */
/*	if (if_queued > IF_THRESH && towrite <= 0) {
 *		error = ENOBUFS;
 *		goto bad;
 *	}
 */

	/*
	 * If small enough for interface, can just send directly.
	 */
	if ((u_int16_t)ip->ip_len <= IF_MTU) {
		ip->ip_len = htons((u_int16_t)ip->ip_len);
		ip->ip_off = htons((u_int16_t)ip->ip_off);
		ip->ip_sum = 0;
		ip->ip_sum = cksum(m, hlen);

		if_output(so, m);
		goto done;
	}

	/*
	 * Too large for interface; fragment if possible.
	 * Must be able to put at least 8 bytes per fragment.
	 */
	if (ip->ip_off & IP_DF) {
		error = -1;
		STAT(ipstat.ips_cantfrag++);
		goto bad;
	}

	len = (IF_MTU - hlen) &~ 7;       /* ip databytes per packet */
	if (len < 8) {
		error = -1;
		goto bad;
	}

    {
	int mhlen, firstlen = len;
	struct mbuf **mnext = &m->m_nextpkt;

	/*
	 * Loop through length of segment after first fragment,
	 * make new header and copy data of each part and link onto chain.
	 */
	m0 = m;
	mhlen = sizeof (struct ip);
	for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
	  register struct ip *mhip;
	  m = m_get();
          if (m == NULL) {
	    error = -1;
	    STAT(ipstat.ips_odropped++);
	    goto sendorfree;
	  }
	  m->m_data += IF_MAXLINKHDR;
	  mhip = mtod(m, struct ip *);
	  *mhip = *ip;

		/* No options */
/*		if (hlen > sizeof (struct ip)) {
 *			mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
 *			mhip->ip_hl = mhlen >> 2;
 *		}
 */
	  m->m_len = mhlen;
	  mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
	  if (ip->ip_off & IP_MF)
	    mhip->ip_off |= IP_MF;
	  if (off + len >= (u_int16_t)ip->ip_len)
	    len = (u_int16_t)ip->ip_len - off;
	  else
	    mhip->ip_off |= IP_MF;
	  mhip->ip_len = htons((u_int16_t)(len + mhlen));

	  if (m_copy(m, m0, off, len) < 0) {
	    error = -1;
	    goto sendorfree;
	  }

	  mhip->ip_off = htons((u_int16_t)mhip->ip_off);
	  mhip->ip_sum = 0;
	  mhip->ip_sum = cksum(m, mhlen);
	  *mnext = m;
	  mnext = &m->m_nextpkt;
	  STAT(ipstat.ips_ofragments++);
	}
	/*
	 * Update first fragment by trimming what's been copied out
	 * and updating header, then send each fragment (in order).
	 */
	m = m0;
	m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len);
	ip->ip_len = htons((u_int16_t)m->m_len);
	ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
	ip->ip_sum = 0;
	ip->ip_sum = cksum(m, hlen);
sendorfree:
	for (m = m0; m; m = m0) {
		m0 = m->m_nextpkt;
                m->m_nextpkt = NULL;
		if (error == 0)
			if_output(so, m);
		else
			m_freem(m);
	}

	if (error == 0)
		STAT(ipstat.ips_fragmented++);
    }

done:
	return (error);

bad:
	m_freem(m0);
	goto done;
}
Example #14
0
static struct mbuf *
DeflateOutput(void *v, struct ccp *ccp, struct link *l __unused,
	      int pri __unused, u_short *proto, struct mbuf *mp)
{
  struct deflate_state *state = (struct deflate_state *)v;
  u_char *wp, *rp;
  int olen, ilen, len, res, flush;
  struct mbuf *mo_head, *mo, *mi_head, *mi;

  ilen = m_length(mp);
  log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", *proto, ilen);
  log_DumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp);

  /* Stuff the protocol in front of the input */
  mi_head = mi = m_get(2, MB_CCPOUT);
  mi->m_next = mp;
  rp = MBUF_CTOP(mi);
  if (*proto < 0x100) {			/* Compress the protocol */
    rp[0] = *proto & 0377;
    mi->m_len = 1;
  } else {				/* Don't compress the protocol */
    rp[0] = *proto >> 8;
    rp[1] = *proto & 0377;
    mi->m_len = 2;
  }

  /* Allocate the initial output mbuf */
  mo_head = mo = m_get(DEFLATE_CHUNK_LEN, MB_CCPOUT);
  mo->m_len = 2;
  wp = MBUF_CTOP(mo);
Example #15
0
/*{{{  main*/
int main(int argc, char *argv[])
{
  /*{{{  variables*/
  enum { NOTHING, OTHER_FS, SAME_FS } in=NOTHING;
  int c;
  int mouse_x,mouse_y;
  int image_width,image_height;
  int image_xoffset=0,image_yoffset=0;
  int my_width,my_height;
  int image_depth,image_size;
  int err=0,usage=0;
  FILE *input=(FILE*)0;
  static struct menu_entry menu[] =
  {
    { "Normal","|n\n" },
    { "Reverse","|r\n" },
    { "-------", "" },
    { "Quit","|q\n" }
  };
  char file[_POSIX_PATH_MAX];
  char event[20];
  /*}}}  */

  /*{{{  parse arguments*/
  while ((c=getopt(argc,argv,"ro:s:"))!=EOF)
  {
    switch (c)
    {
      /*{{{  r*/
      case 'r': display_op=BIT_NOT(BIT_SRC); break;
      /*}}}  */
      /*{{{  o file*/
      case 'o':
      {
        if ((input=fopen(optarg,"r"))==(FILE*)0)
        {
          fprintf(stderr,"%s: Can't open %s\r\n",argv[0],optarg);
          err=1;
        }
        else in=OTHER_FS;
        break;
      }
      /*}}}  */
      /*{{{  s file*/
      case 's':
      {
        char *cwd;

        in=SAME_FS;
        if (*optarg!='/' && *optarg!='.')
        {
          if ((cwd=getcwd((char*)0,(size_t)0))!=(char*)0) { strcpy(file,cwd); strcat(file,"/"); strcat(file,optarg); }
          else { fprintf(stderr,"%s: Can't get current directory\r\n",argv[0]); err=1; }
        }
        else strcpy(file,optarg);
        break;
      }
      /*}}}  */
      /*{{{  default*/
      default:
      {
        usage=1;
        break;
      }
      /*}}}  */
    }
  }
  if (err) exit(err);
  if (usage || optind!=argc)
  {
    fprintf(stderr,"Usage: mgrview [-o file | -s file]\n");
    exit(1);
  }
  if (in==NOTHING) { in=OTHER_FS; input=stdin; }
  /*}}}  */
  /*{{{  setup*/
  ckmgrterm(argv[0]);
  m_setup(M_MODEOK);
  signal(SIGINT,clean);
  signal(SIGTERM,clean);
  signal(SIGPIPE,clean);
  m_ttyset();
  m_push(P_ALL);
  m_setmode(M_ABS);
  m_setcursor(CS_INVIS);
  menu_load(1,4,menu);
  m_setevent(REDRAW, "|R\n");
  m_setevent(RESHAPE, "|R\n");
  m_setevent(BUTTON_1,"|!%p!\n");
  m_setevent(BUTTON_2,"|m\n");
  m_flush();
  /*}}}  */
  if (in==OTHER_FS)
  {
    /*{{{  variables*/
    struct b_header bh;
    void *bp;
    /*}}}  */

    /*{{{  load bitmap to client space*/
    if (fread(&bh,sizeof(struct b_header),1,input)!=1)
    {
      fprintf(stderr,"%s: Can't read header of bitmap.\r\n",argv[0]);
      clean(1);
    }
    if (!B_ISHDR8(&bh))
    {
      fprintf(stderr,"%s: No MGR bitmap or old format.\r\n",argv[0]);
      clean(1);
    }
    B_GETHDR8(&bh,image_width,image_height,image_depth);
    image_size=B_SIZE8(image_width,image_height,image_depth);
    /*}}}  */
    /*{{{  transfer bitmap to server space*/
    m_func(BIT_SRC);
    m_bitcreate(IMAGE_BITMAP,image_width,image_height);
    m_bitldto(image_width,image_height,0,0,IMAGE_BITMAP,image_size);
    bp=malloc(image_size);
    fread(bp,image_size,1,input);
    fwrite(bp,image_size,1,m_termout);
    free(bp);
    /*}}}  */
  }
  else if (in==SAME_FS)
  /*{{{  transfer bitmap from server fs to server space*/
  {
  m_bitfromfile(IMAGE_BITMAP,file);
  m_get();
  if (sscanf(m_linebuf,"%d %d",&image_width,&image_height)<2)
  {
    fprintf(stderr,"%s: MGR server can't load MGR bitmap.\r\n",argv[0]);
    clean(1);
  }
  }
  /*}}}  */
  /*{{{  user interaction*/
  m_getwindowsize(&my_width,&my_height);
  display(image_xoffset,image_yoffset,my_width,my_height,image_width,image_height);
  m_flush();
  do
  {
    if (m_getevent(10000,&c,event,sizeof(event))==EV_EVENTSTR) switch (event[0])
    {
      /*{{{  n,r*/
      case 'n':
      case 'r':
      {
        display_op=(c=='n' ? BIT_SRC : BIT_NOT(BIT_SRC));
        m_func(display_op);
        m_bitcopyto(image_xoffset,image_yoffset,image_width,image_height,0,0,WINDOW_BITMAP,IMAGE_BITMAP);
        m_flush();
        break;
      }
      /*}}}  */
      /*{{{  m -- left button displays menu*/
      case 'm':
      {
        m_selectmenu(1);
        m_flush();
        break;
      }
      /*}}}  */
      /*{{{  !%d %d! -- right button*/
      case '!':
      {
        sscanf(event,"!%d %d!",&mouse_x,&mouse_y);
        /*{{{  compute new x start*/
        if (my_width>image_width) image_xoffset=0;
        else if (mouse_x<=0) image_xoffset=0;
        else if (mouse_x>=my_width) image_xoffset=my_width-image_width;
        else
        {
          /*{{{  move x start by difference from mouse and middle*/
          image_xoffset=image_xoffset-(mouse_x-my_width/2);
          /*}}}  */
          /*{{{  check and corrent range of x start*/
          if (image_xoffset<my_width-image_width) image_xoffset=my_width-image_width;
          else if (image_xoffset>0) image_xoffset=0;
          /*}}}  */
        }
        /*}}}  */
        /*{{{  compute new y start*/
        if (my_height>image_height) image_yoffset=0;
        else if (mouse_y<=0) image_yoffset=0;
        else if (mouse_y>=my_height) image_yoffset=my_height-image_height;
        else
        {
          /*{{{  move y start by difference from mouse and middle*/
          image_yoffset=image_yoffset-(mouse_y-my_height/2);
          /*}}}  */
          /*{{{  check and corrent range of y start*/
          if (image_yoffset<my_height-image_height) image_yoffset=my_height-image_height;
          else if (image_yoffset>0) image_yoffset=0;
          /*}}}  */
        }
        /*}}}  */
        display(image_xoffset,image_yoffset,my_width,my_height,image_width,image_height);
        m_flush();
        break;
      }
      /*}}}  */
      /*{{{  R -- redraw*/
      case 'R':
      {
        m_getwindowsize(&my_width,&my_height);
        /*{{{  compute new x offset*/
        if (my_width<image_width)
        {
          if (image_xoffset<my_width-image_width) image_xoffset=my_width-image_width;
        }
        else image_xoffset=0;
        /*}}}  */
        /*{{{  compute new y offset*/
        if (my_height<image_height)
        {
          if (image_yoffset<my_height-image_height) image_yoffset=my_height-image_height;
        }
        else image_yoffset=0;
        /*}}}  */
        m_func(BIT_CLR);
        m_bitwrite(0,0,my_width,my_height);
        m_func(display_op);
        m_bitcopyto(image_xoffset,image_yoffset,image_width,image_height,0,0,WINDOW_BITMAP,IMAGE_BITMAP);
        m_flush();
        break;
      }
      /*}}}  */
    }
  } while (event[0]!='q');
  /*}}}  */
  /*{{{  exit*/
  m_bitdestroy(IMAGE_BITMAP);
  clean(0);
  /*}}}  */
  return 255;
}
Example #16
0
/*  Routine to take the matrix given and calculate the log-
 * determinant, by calling LU decomposition routine and
 * then multiplying down diagonals. Returns the
 * log-determinant calculated.*/
double * determinant(void){
  int a,max,c;
  extern int branches;
  double *det;
  extern int mode;
  extern int nodecount;
  extern double **expect;
  extern double **rootedexpect;
  extern int individual;
  extern int interesting_branches[];
  extern int is_kappa;
  double **matrix;
  MAT * matrix2;

  is_kappa=0;
  if(ISMODE(HKY) && NOTMODE(NOKAPPA))
    is_kappa=1;
  matrix=expect;
  max=branches;
  if(ISMODE(ROOTED)){ /*  If want rooted tree then create new*/
    planttree(expect,rootedexpect);   /* matrix*/
    matrix=rootedexpect;
    max=nodecount+2;
    if(ISMODE(NODEASROOT))
      max=nodecount+1;
  }

  if(ISMODE(MATRICES)){  /* If want intermediate matrices dumped*/
    dump(matrix,max+is_kappa,"Full matrix");
  }

  if(ISMODE(INDIVIDUAL)){ /*  We want information about some, but
                           * not all of the elements*/
    if(NOTMODE(DETINDIV)){
      det=calloc(individual+is_kappa,sizeof(double));
      for(a=0;a<individual;a++)
        det[a]=matrix[interesting_branches[a]][interesting_branches[a]];
      if(is_kappa==1)
	det[individual]=matrix[max][max];
      is_kappa=0;
      return det;
    }

    /*  Case - we want the determinate of the sub-matrix formed 
     * by several parameters*/
    /*  Get memory for new matrix*/
    matrix2 = m_get(individual+is_kappa,individual+is_kappa);
    if(NULL==matrix2){
	    nomemory();
    }
    m_zero(matrix2);


    /*  Creates the sub-matrix from the original expected information
     * matrix*/
    for(a=0;a<individual;a++)
      for(c=0;c<individual;c++)
	matrix2->me[a][c]=matrix[interesting_branches[a]][interesting_branches[c]];
    if(is_kappa==1){
      matrix2->me[individual][individual]=matrix[max][max];
    }
    
    max=individual;
    if(ISMODE(MATRICES))
      dump(matrix2->me,max,"Sub-matrix to be calculated");
  } else {
      matrix2 = m_get(max,max);
      if(NULL==matrix2){
          nomemory();
      }
      m_zero(matrix2);
      for ( a=0 ; a<max ; a++){
          for ( c=0 ; c<max ; c++){
              matrix2->me[a][c] = matrix[a][c];
          }
      }
  }
 
  /*  Perform LU decomposition on whichever matrix we've been handed*/
  det=calloc(1+is_kappa,sizeof(double));
  matrix2=CHfactor(matrix2);

  /*  The determinant of the matrix is the product of
   * the diagonal elements of the decomposed form*/
  for(a=0;a<max;a++){
    det[0] += 2.0 * log(matrix2->me[a][a]);
  }
  if(is_kappa==1){
    det[1] = 2.0 * log(matrix2->me[max][max]);
  }

  M_FREE(matrix2);

  return det;
}
Example #17
0
/*
 * mbuf_copyback differs from m_copyback in a few ways:
 * 1) mbuf_copyback will allocate clusters for new mbufs we append
 * 2) mbuf_copyback will grow the last mbuf in the chain if possible
 * 3) mbuf_copyback reports whether or not the operation succeeded
 * 4) mbuf_copyback allows the caller to specify M_WAITOK or M_NOWAIT
 */
errno_t
mbuf_copyback(
	mbuf_t		m,
	size_t		off,
	size_t		len,
	const void	*data,
	mbuf_how_t	how)
{
	size_t	mlen;
	mbuf_t	m_start = m;
	mbuf_t	n;
	int		totlen = 0;
	errno_t		result = 0;
	const char	*cp = data;

	if (m == NULL || len == 0 || data == NULL)
		return (EINVAL);

	while (off > (mlen = m->m_len)) {
		off -= mlen;
		totlen += mlen;
		if (m->m_next == 0) {
			n = m_getclr(how, m->m_type);
			if (n == 0) {
				result = ENOBUFS;
				goto out;
			}
			n->m_len = MIN(MLEN, len + off);
			m->m_next = n;
		}
		m = m->m_next;
	}

	while (len > 0) {
		mlen = MIN(m->m_len - off, len);
		if (mlen < len && m->m_next == NULL &&
		    mbuf_trailingspace(m) > 0) {
			size_t	grow = MIN(mbuf_trailingspace(m), len - mlen);
			mlen += grow;
			m->m_len += grow;
		}
		bcopy(cp, off + (char *)mbuf_data(m), (unsigned)mlen);
		cp += mlen;
		len -= mlen;
		mlen += off;
		off = 0;
		totlen += mlen;
		if (len == 0)
			break;
		if (m->m_next == 0) {
			n = m_get(how, m->m_type);
			if (n == NULL) {
				result = ENOBUFS;
				goto out;
			}
			if (len > MINCLSIZE) {
				/*
				 * cluster allocation failure is okay,
				 * we can grow chain
				 */
				mbuf_mclget(how, m->m_type, &n);
			}
			n->m_len = MIN(mbuf_maxlen(n), len);
			m->m_next = n;
		}
		m = m->m_next;
	}

out:
	if ((m_start->m_flags & M_PKTHDR) && (m_start->m_pkthdr.len < totlen))
		m_start->m_pkthdr.len = totlen;

	return (result);
}
Example #18
0
/*
 * IP output.  The packet in mbuf chain m contains a skeletal IP
 * header (with len, off, ttl, proto, tos, src, dst).
 * The mbuf chain containing the packet will be freed.
 * The mbuf opt, if present, will not be freed.
 */
int
ip_output(struct socket *so, struct mbuf *m0)
{
	Slirp *slirp = m0->slirp;
	struct ip *ip;
	struct mbuf *m = m0;
	int hlen = sizeof(struct ip );
	int len, off, error = 0;

	DEBUG_CALL("ip_output");
	DEBUG_ARG("so = %lx", (long)so);
	DEBUG_ARG("m0 = %lx", (long)m0);

	ip = mtod(m, struct ip *);
	/*
	 * Fill in IP header.
	 */
	ip->ip_v = IPVERSION;
	ip->ip_off &= IP_DF;
	ip->ip_id = htons(slirp->ip_id++);
	ip->ip_hl = hlen >> 2;

	/*
	 * If small enough for interface, can just send directly.
	 */
	if ((u_int16_t)ip->ip_len <= IF_MTU) {
		ip->ip_len = htons((u_int16_t)ip->ip_len);
		ip->ip_off = htons((u_int16_t)ip->ip_off);
		ip->ip_sum = 0;
		ip->ip_sum = cksum(m, hlen);

		if_output(so, m);
		goto done;
	}

	/*
	 * Too large for interface; fragment if possible.
	 * Must be able to put at least 8 bytes per fragment.
	 */
	if (ip->ip_off & IP_DF) {
		error = -1;
		goto bad;
	}

	len = (IF_MTU - hlen) &~ 7;       /* ip databytes per packet */
	if (len < 8) {
		error = -1;
		goto bad;
	}

    {
	int mhlen, firstlen = len;
	struct mbuf **mnext = &m->m_nextpkt;

	/*
	 * Loop through length of segment after first fragment,
	 * make new header and copy data of each part and link onto chain.
	 */
	m0 = m;
	mhlen = sizeof (struct ip);
	for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
	  struct ip *mhip;
	  m = m_get(slirp);
          if (m == NULL) {
	    error = -1;
	    goto sendorfree;
	  }
	  m->m_data += IF_MAXLINKHDR;
	  mhip = mtod(m, struct ip *);
	  *mhip = *ip;

	  m->m_len = mhlen;
	  mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
	  if (ip->ip_off & IP_MF)
	    mhip->ip_off |= IP_MF;
	  if (off + len >= (u_int16_t)ip->ip_len)
	    len = (u_int16_t)ip->ip_len - off;
	  else
	    mhip->ip_off |= IP_MF;
	  mhip->ip_len = htons((u_int16_t)(len + mhlen));

	  if (m_copy(m, m0, off, len) < 0) {
	    error = -1;
	    goto sendorfree;
	  }

	  mhip->ip_off = htons((u_int16_t)mhip->ip_off);
	  mhip->ip_sum = 0;
	  mhip->ip_sum = cksum(m, mhlen);
	  *mnext = m;
	  mnext = &m->m_nextpkt;
	}
	/*
	 * Update first fragment by trimming what's been copied out
	 * and updating header, then send each fragment (in order).
	 */
	m = m0;
	m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len);
	ip->ip_len = htons((u_int16_t)m->m_len);
	ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
	ip->ip_sum = 0;
	ip->ip_sum = cksum(m, hlen);
sendorfree:
	for (m = m0; m; m = m0) {
		m0 = m->m_nextpkt;
                m->m_nextpkt = NULL;
		if (error == 0)
			if_output(so, m);
		else
			m_freem(m);
	}
    }

done:
	return (error);

bad:
	m_freem(m0);
	goto done;
}
Example #19
0
File: bootp.c Project: 0-14N/NDroid
static void bootp_reply(const struct bootp_t *bp)
{
    BOOTPClient *bc = NULL;
    struct mbuf *m;
    struct bootp_t *rbp;
    struct sockaddr_in saddr, daddr;
    struct in_addr dns_addr;
    const struct in_addr *preq_addr;
    int dhcp_msg_type, val;
    uint8_t *q;

    /* extract exact DHCP msg type */
    dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
    dprintf("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
    if (preq_addr)
        dprintf(" req_addr=%08x\n", ntohl(preq_addr->s_addr));
    else
        dprintf("\n");

    if (dhcp_msg_type == 0)
        dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */

    if (dhcp_msg_type != DHCPDISCOVER &&
        dhcp_msg_type != DHCPREQUEST)
        return;
    /* XXX: this is a hack to get the client mac address */
    memcpy(client_ethaddr, bp->bp_hwaddr, 6);

    if ((m = m_get()) == NULL)
        return;
    m->m_data += IF_MAXLINKHDR;
    rbp = (struct bootp_t *)m->m_data;
    m->m_data += sizeof(struct udpiphdr);
    memset(rbp, 0, sizeof(struct bootp_t));

    if (dhcp_msg_type == DHCPDISCOVER) {
        if (preq_addr) {
            bc = request_addr(preq_addr, client_ethaddr);
            if (bc) {
                daddr.sin_addr = *preq_addr;
            }
        }
        if (!bc) {
         new_addr:
            bc = get_new_addr(&daddr.sin_addr, client_ethaddr);
            if (!bc) {
                dprintf("no address left\n");
                return;
            }
        }
        memcpy(bc->macaddr, client_ethaddr, 6);
    } else if (preq_addr) {
        bc = request_addr(preq_addr, client_ethaddr);
        if (bc) {
            daddr.sin_addr = *preq_addr;
            memcpy(bc->macaddr, client_ethaddr, 6);
        } else {
            daddr.sin_addr.s_addr = 0;
        }
    } else {
        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
        if (!bc) {
            /* if never assigned, behaves as if it was already
               assigned (windows fix because it remembers its address) */
            goto new_addr;
        }
    }

    saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
    saddr.sin_port = htons(BOOTP_SERVER);

    daddr.sin_port = htons(BOOTP_CLIENT);

    rbp->bp_op = BOOTP_REPLY;
    rbp->bp_xid = bp->bp_xid;
    rbp->bp_htype = 1;
    rbp->bp_hlen = 6;
    memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);

    rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */

    q = rbp->bp_vend;
    memcpy(q, rfc1533_cookie, 4);
    q += 4;

    if (bc) {
        dprintf("%s addr=%08x\n",
                (dhcp_msg_type == DHCPDISCOVER) ? "offered" : "ack'ed",
                ntohl(daddr.sin_addr.s_addr));

        if (dhcp_msg_type == DHCPDISCOVER) {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPOFFER;
        } else /* DHCPREQUEST */ {
            *q++ = RFC2132_MSG_TYPE;
            *q++ = 1;
            *q++ = DHCPACK;
        }

        if (bootp_filename)
            snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
                     bootp_filename);

        *q++ = RFC2132_SRV_ID;
        *q++ = 4;
        memcpy(q, &saddr.sin_addr, 4);
        q += 4;

        *q++ = RFC1533_NETMASK;
        *q++ = 4;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0xff;
        *q++ = 0x00;

        if (!slirp_restrict) {
            *q++ = RFC1533_GATEWAY;
            *q++ = 4;
            memcpy(q, &saddr.sin_addr, 4);
            q += 4;

            *q++ = RFC1533_DNS;
            *q++ = 4;
            dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
            memcpy(q, &dns_addr, 4);
            q += 4;
        }

        *q++ = RFC2132_LEASE_TIME;
        *q++ = 4;
        val = htonl(LEASE_TIME);
        memcpy(q, &val, 4);
        q += 4;

        if (*slirp_hostname) {
            val = strlen(slirp_hostname);
            *q++ = RFC1533_HOSTNAME;
            *q++ = val;
            memcpy(q, slirp_hostname, val);
            q += val;
        }
    } else {
        static const char nak_msg[] = "requested address not available";

        dprintf("nak'ed addr=%08x\n", ntohl(preq_addr->s_addr));

        *q++ = RFC2132_MSG_TYPE;
        *q++ = 1;
        *q++ = DHCPNAK;

        *q++ = RFC2132_MESSAGE;
        *q++ = sizeof(nak_msg) - 1;
        memcpy(q, nak_msg, sizeof(nak_msg) - 1);
        q += sizeof(nak_msg) - 1;
    }
    *q++ = RFC1533_END;

    daddr.sin_addr.s_addr = 0xffffffffu;

    m->m_len = sizeof(struct bootp_t) -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
Example #20
0
int main(int argc, char *argv[])
{
    int opt;
    struct pmf *c;
    struct pmf *u;
    struct pmf *c1;
    uint64_t time_start, time_end;
    int n, i, j;
    Real prob = 0.0;
    MAT *matrix;

    opt = opts_parse(argc, argv);

    if (strcmp(ofile, "") == 0) {
	fprintf(stderr, "You must specify an output file.mat\n");
	exit(0);
    }
    c = load(argv[opt], Nc);
    c1 = pmf2cdf(c);

//print(c1,"c1");

    time_start = get_time();
    switch (model) {
    case ETFAMODEL:{
	    if (z == 0)
		u = load(argv[opt + 1], Nc);
	    else {
		u = pmf_create(Nc, 0);
		pmf_set(u, z, 1.0);

	    }
	    n = 100;
	    matrix = m_get(n, n);
	    for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
		    prob = prob_efta(i, j, Q, c, u);
		    m_set_val(matrix, i, j, prob);
		}
	    }
	    break;
	}
    case LASTMODEL:{
	    if (d == 0)
		d = Q;
	    n = pmf_max(c) / d * 3;
	    matrix = m_get(n, n);
	    for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
		    prob = prob_last(i, j, Q, z, d, c1);
		    m_set_val(matrix, i, j, prob);
		}
	    }
	    break;
	}
    case RTSSMODEL:{
	    n = 10;
	    matrix = m_get(n, n);
	    for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
		    prob = prob_rtss(i, j, Q, z, c);
		    m_set_val(matrix, i, j, prob);
		}
	    }
	    break;
	}
    default:
	fprintf(stderr, "Choose a model please\n");
	exit(0);
    }
    time_end = get_time();


/*for (i=0; i<n; i++){
     for (j=0; j<n; j++){
       printf("%f ",m_get_val(matrix,i,j));
     }
       printf("\n");
    
}*/
    //print(matrix);
    FILE *fm = fopen(ofile, "w");
    m_save(fm, matrix, "matrix");
    fclose(fm);
    return (0);
}
Example #21
0
void ellipsetrack(avi_t *video, double *xc0, double *yc0, int Nc, int R, int Np, int Nf) {
	/*
	% ELLIPSETRACK tracks cells in the movie specified by 'video', at
	%  locations 'xc0'/'yc0' with radii R using an ellipse with Np discrete
	%  points, starting at frame number one and stopping at frame number 'Nf'.
	%
	% INPUTS:
	%   video.......pointer to avi video object
	%   xc0,yc0.....initial center location (Nc entries)
	%   Nc..........number of cells
	%   R...........initial radius
	%   Np..........nbr of snaxels points per snake
	%   Nf..........nbr of frames in which to track
	%
	% Matlab code written by: DREW GILLIAM (based on code by GANG DONG /
	%                                                        NILANJAN RAY)
	% Ported to C by: MICHAEL BOYER
	*/
	
	int i, j;
	
	// Compute angle parameter
	double *t = (double *) malloc(sizeof(double) * Np);
	double increment = (2.0 * PI) / (double) Np;
	for (i = 0; i < Np; i++) {
		t[i] =  increment * (double) i ;
	}

	// Allocate space for a snake for each cell in each frame
	double **xc = alloc_2d_double(Nc, Nf + 1);
	double **yc = alloc_2d_double(Nc, Nf + 1);
	double ***r = alloc_3d_double(Nc, Np, Nf + 1);
	double ***x = alloc_3d_double(Nc, Np, Nf + 1);
	double ***y = alloc_3d_double(Nc, Np, Nf + 1);
	
	// Save the first snake for each cell
	for (i = 0; i < Nc; i++) {
		xc[i][0] = xc0[i];
		yc[i][0] = yc0[i];
		for (j = 0; j < Np; j++) {
			r[i][j][0] = (double) R;
		}
	}
	
	// Generate ellipse points for each cell
	for (i = 0; i < Nc; i++) {
		for (j = 0; j < Np; j++) {
			x[i][j][0] = xc[i][0] + (r[i][j][0] * cos(t[j]));
			y[i][j][0] = yc[i][0] + (r[i][j][0] * sin(t[j]));
		}
	}
	
	// Keep track of the total time spent on computing
	//  the MGVF matrix and evolving the snakes
	long long  MGVF_time = 0;
	long long snake_time = 0;
	
	
	// Process each frame
	int frame_num, cell_num;
	for (frame_num = 1; frame_num <= Nf; frame_num++) {	 
		printf("\rProcessing frame %d / %d", frame_num, Nf);
		fflush(stdout);
		
		// Get the current video frame and its dimensions
		MAT *I = get_frame(video, frame_num, 0, 1);
		int Ih = I->m;
		int Iw = I->n;
	    
	    // Set the current positions equal to the previous positions		
		for (i = 0; i < Nc; i++) {
			xc[i][frame_num] = xc[i][frame_num - 1];
			yc[i][frame_num] = yc[i][frame_num - 1];
			for (j = 0; j < Np; j++) {
				r[i][j][frame_num] = r[i][j][frame_num - 1];
			}
		}
		
		// Split the work among multiple threads, if OPEN is defined
		#ifdef OPEN
		#pragma omp parallel for num_threads(omp_num_threads) private(i, j)
		#endif
		// Track each cell
		for (cell_num = 0; cell_num < Nc; cell_num++) {
			// Make copies of the current cell's location
			double xci = xc[cell_num][frame_num];
			double yci = yc[cell_num][frame_num];
			double *ri = (double *) malloc(sizeof(double) * Np);
			for (j = 0; j < Np; j++) {
				ri[j] = r[cell_num][j][frame_num];
			}
			
			// Add up the last ten y-values for this cell
			//  (or fewer if there are not yet ten previous frames)
			double ycavg = 0.0;
			for (i = (frame_num > 10 ? frame_num - 10 : 0); i < frame_num; i++) {
				ycavg += yc[cell_num][i];
			}
			// Compute the average of the last ten y-values
			//  (this represents the expected y-location of the cell)
			ycavg = ycavg / (double) (frame_num > 10 ? 10 : frame_num);
			
			// Determine the range of the subimage surrounding the current position
			int u1 = max(xci - 4.0 * R + 0.5, 0 );
			int u2 = min(xci + 4.0 * R + 0.5, Iw - 1);
			int v1 = max(yci - 2.0 * R + 1.5, 0 );    
			int v2 = min(yci + 2.0 * R + 1.5, Ih - 1);
			
			// Extract the subimage
			MAT *Isub = m_get(v2 - v1 + 1, u2 - u1 + 1);
			for (i = v1; i <= v2; i++) {
				for (j = u1; j <= u2; j++) {
					m_set_val(Isub, i - v1, j - u1, m_get_val(I, i, j));
				}
			}
			
	        // Compute the subimage gradient magnitude			
			MAT *Ix = gradient_x(Isub);
			MAT *Iy = gradient_y(Isub);
			MAT *IE = m_get(Isub->m, Isub->n);
			for (i = 0; i < Isub->m; i++) {
				for (j = 0; j < Isub->n; j++) {
					double temp_x = m_get_val(Ix, i, j);
					double temp_y = m_get_val(Iy, i, j);
					m_set_val(IE, i, j, sqrt((temp_x * temp_x) + (temp_y * temp_y)));
				}
			}
			
			// Compute the motion gradient vector flow (MGVF) edgemaps
			long long MGVF_start_time = get_time();
			MAT *IMGVF = MGVF(IE, 1, 1);
			MGVF_time += get_time() - MGVF_start_time;
			
			// Determine the position of the cell in the subimage			
			xci = xci - (double) u1;
			yci = yci - (double) (v1 - 1);
			ycavg = ycavg - (double) (v1 - 1);
			
			// Evolve the snake
			long long snake_start_time = get_time();
			ellipseevolve(IMGVF, &xci, &yci, ri, t, Np, (double) R, ycavg);
			snake_time += get_time() - snake_start_time;
			
			// Compute the cell's new position in the full image
			xci = xci + u1;
			yci = yci + (v1 - 1);
			
			// Store the new location of the cell and the snake
			xc[cell_num][frame_num] = xci;
			yc[cell_num][frame_num] = yci;
			for (j = 0; j < Np; j++) {
				r[cell_num][j][frame_num] = ri[j];
				x[cell_num][j][frame_num] = xc[cell_num][frame_num] + (ri[j] * cos(t[j]));
				y[cell_num][j][frame_num] = yc[cell_num][frame_num] + (ri[j] * sin(t[j]));
			}
			
			// Output the updated center of each cell
			//printf("%d,%f,%f\n", cell_num, xci[cell_num], yci[cell_num]);
			
			// Free temporary memory
			m_free(IMGVF);
			free(ri);
	    }

#ifdef OUTPUT
		if (frame_num == Nf)
		  {
		    FILE * pFile;
		    pFile = fopen ("result.txt","w+");
	
		    for (cell_num = 0; cell_num < Nc; cell_num++)		
		      fprintf(pFile,"\n%d,%f,%f", cell_num, xc[cell_num][Nf], yc[cell_num][Nf]);

		    fclose (pFile);
		  }
		
#endif
	
	
		// Output a new line to visually distinguish the output from different frames
		//printf("\n");
	}
	
	// Free temporary memory
	free(t);
	free_2d_double(xc);
	free_2d_double(yc);
	free_3d_double(r);
	free_3d_double(x);
	free_3d_double(y);
	
	// Report average processing time per frame
	printf("\n\nTracking runtime (average per frame):\n");
	printf("------------------------------------\n");
	printf("MGVF computation: %.5f seconds\n", ((float) (MGVF_time)) / (float) (1000*1000*Nf));
	printf(" Snake evolution: %.5f seconds\n", ((float) (snake_time)) / (float) (1000*1000*Nf));
}
Example #22
0
/*
 * recvfrom() a UDP socket
 */
void
sorecvfrom(struct socket *so)
{
	struct sockaddr_in addr;
	socklen_t addrlen = sizeof(struct sockaddr_in);

	DEBUG_CALL("sorecvfrom");
	DEBUG_ARG("so = %p", so);

	if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
	  char buff[256];
	  int len;

	  len = recvfrom(so->s, buff, 256, 0,
			 (struct sockaddr *)&addr, &addrlen);
	  /* XXX Check if reply is "correct"? */

	  if(len == -1 || len == 0) {
	    u_char code=ICMP_UNREACH_PORT;

	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;

	    DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
			errno,strerror(errno)));
	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
	  } else {
	    icmp_reflect(so->so_m);
            so->so_m = NULL; /* Don't m_free() it again! */
	  }
	  /* No need for this socket anymore, udp_detach it */
	  udp_detach(so);
	} else {                            	/* A "normal" UDP packet */
	  struct mbuf *m;
          int len;
#ifdef _WIN32
          unsigned long n;
#else
          int n;
#endif

	  m = m_get(so->slirp);
	  if (!m) {
	      return;
	  }
	  m->m_data += IF_MAXLINKHDR;

	  /*
	   * XXX Shouldn't FIONREAD packets destined for port 53,
	   * but I don't know the max packet size for DNS lookups
	   */
	  len = M_FREEROOM(m);
	  /* if (so->so_fport != htons(53)) { */
	  ioctlsocket(so->s, FIONREAD, &n);

	  if (n > len) {
	    n = (m->m_data - m->m_dat) + m->m_len + n + 1;
	    m_inc(m, n);
	    len = M_FREEROOM(m);
	  }
	  /* } */

	  m->m_len = recvfrom(so->s, m->m_data, len, 0,
			      (struct sockaddr *)&addr, &addrlen);
	  DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
		      m->m_len, errno,strerror(errno)));
	  if(m->m_len<0) {
	    u_char code=ICMP_UNREACH_PORT;

	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;

	    DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
	    m_free(m);
	  } else {
	  /*
	   * Hack: domain name lookup will be used the most for UDP,
	   * and since they'll only be used once there's no need
	   * for the 4 minute (or whatever) timeout... So we time them
	   * out much quicker (10 seconds  for now...)
	   */
	    if (so->so_expire) {
	      if (so->so_fport == htons(53))
		so->so_expire = curtime + SO_EXPIREFAST;
	      else
		so->so_expire = curtime + SO_EXPIRE;
	    }

	    /*
	     * If this packet was destined for CTL_ADDR,
	     * make it look like that's where it came from, done by udp_output
	     */
	    udp_output(so, m, &addr);
	  } /* rx error */
	} /* if ping packet */
}
Example #23
0
/*
 * Slightly changed version of sosend()
 */
static int
kttcp_sosend(struct socket *so, unsigned long long slen,
	     unsigned long long *done, struct lwp *l, int flags)
{
	struct mbuf **mp, *m, *top;
	long space, len, mlen;
	int error, dontroute, atomic;
	long long resid;

	atomic = sosendallatonce(so);
	resid = slen;
	top = NULL;
	/*
	 * In theory resid should be unsigned.
	 * However, space must be signed, as it might be less than 0
	 * if we over-committed, and we must use a signed comparison
	 * of space and resid.  On the other hand, a negative resid
	 * causes us to loop sending 0-length segments to the protocol.
	 */
	if (resid < 0) {
		error = EINVAL;
		goto out;
	}
	dontroute =
	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
	    (so->so_proto->pr_flags & PR_ATOMIC);
	l->l_ru.ru_msgsnd++;
#define	snderr(errno)	{ error = errno; goto release; }
	solock(so);
 restart:
	if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
		goto out;
	do {
		if (so->so_state & SS_CANTSENDMORE)
			snderr(EPIPE);
		if (so->so_error) {
			error = so->so_error;
			so->so_error = 0;
			goto release;
		}
		if ((so->so_state & SS_ISCONNECTED) == 0) {
			if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
				snderr(ENOTCONN);
			} else {
				snderr(EDESTADDRREQ);
			}
		}
		space = sbspace(&so->so_snd);
		if (flags & MSG_OOB)
			space += 1024;
		if ((atomic && resid > so->so_snd.sb_hiwat))
			snderr(EMSGSIZE);
		if (space < resid && (atomic || space < so->so_snd.sb_lowat)) {
			if (so->so_state & SS_NBIO)
				snderr(EWOULDBLOCK);
			SBLASTRECORDCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 1");
			SBLASTMBUFCHK(&so->so_rcv,
			    "kttcp_soreceive sbwait 1");
			sbunlock(&so->so_snd);
			error = sbwait(&so->so_snd);
			if (error)
				goto out;
			goto restart;
		}
		mp = &top;
		do {
			sounlock(so);
			do {
				if (top == 0) {
					m = m_gethdr(M_WAIT, MT_DATA);
					mlen = MHLEN;
					m->m_pkthdr.len = 0;
					m->m_pkthdr.rcvif = NULL;
				} else {
					m = m_get(M_WAIT, MT_DATA);
					mlen = MLEN;
				}
				if (resid >= MINCLSIZE && space >= MCLBYTES) {
					m_clget(m, M_WAIT);
					if ((m->m_flags & M_EXT) == 0)
						goto nopages;
					mlen = MCLBYTES;
#ifdef	MAPPED_MBUFS
					len = lmin(MCLBYTES, resid);
#else
					if (atomic && top == 0) {
						len = lmin(MCLBYTES - max_hdr,
						    resid);
						m->m_data += max_hdr;
					} else
						len = lmin(MCLBYTES, resid);
#endif
					space -= len;
				} else {
nopages:
					len = lmin(lmin(mlen, resid), space);
					space -= len;
					/*
					 * For datagram protocols, leave room
					 * for protocol headers in first mbuf.
					 */
					if (atomic && top == 0 && len < mlen)
						MH_ALIGN(m, len);
				}
				resid -= len;
				m->m_len = len;
				*mp = m;
				top->m_pkthdr.len += len;
				if (error)
					goto release;
				mp = &m->m_next;
				if (resid <= 0) {
					if (flags & MSG_EOR)
						top->m_flags |= M_EOR;
					break;
				}
			} while (space > 0 && atomic);
			solock(so);

			if (so->so_state & SS_CANTSENDMORE)
				snderr(EPIPE);
			if (dontroute)
				so->so_options |= SO_DONTROUTE;
			if (resid > 0)
				so->so_state |= SS_MORETOCOME;
			if (flags & MSG_OOB)
				error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so,
				    top, NULL);
			else
				error = (*so->so_proto->pr_usrreqs->pr_send)(so,
				    top, NULL, NULL, l);
			if (dontroute)
				so->so_options &= ~SO_DONTROUTE;
			if (resid > 0)
				so->so_state &= ~SS_MORETOCOME;
			top = 0;
			mp = &top;
			if (error)
				goto release;
		} while (resid && space > 0);
	} while (resid);

 release:
	sbunlock(&so->so_snd);
 out:
 	sounlock(so);
	if (top)
		m_freem(top);
	*done = slen - resid;
#if 0
	printf("sosend: error %d slen %llu resid %lld\n", error, slen, resid);
#endif
	return (error);
}
Example #24
0
/*
 * Implement receive operations on a socket.
 *
 * We depend on the way that records are added to the signalsockbuf
 * by sbappend*.  In particular, each record (mbufs linked through m_next)
 * must begin with an address if the protocol so specifies,
 * followed by an optional mbuf or mbufs containing ancillary data,
 * and then zero or more mbufs of data.
 *
 * Although the signalsockbuf is locked, new data may still be appended.
 * A token inside the ssb_lock deals with MP issues and still allows
 * the network to access the socket if we block in a uio.
 *
 * The caller may receive the data as a single mbuf chain by supplying
 * an mbuf **mp0 for use in returning the chain.  The uio is then used
 * only for the count in uio_resid.
 */
int
soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio,
	  struct sockbuf *sio, struct mbuf **controlp, int *flagsp)
{
	struct mbuf *m, *n;
	struct mbuf *free_chain = NULL;
	int flags, len, error, offset;
	struct protosw *pr = so->so_proto;
	int moff, type = 0;
	size_t resid, orig_resid;

	if (uio)
		resid = uio->uio_resid;
	else
		resid = (size_t)(sio->sb_climit - sio->sb_cc);
	orig_resid = resid;

	if (psa)
		*psa = NULL;
	if (controlp)
		*controlp = NULL;
	if (flagsp)
		flags = *flagsp &~ MSG_EOR;
	else
		flags = 0;
	if (flags & MSG_OOB) {
		m = m_get(MB_WAIT, MT_DATA);
		if (m == NULL)
			return (ENOBUFS);
		error = so_pru_rcvoob(so, m, flags & MSG_PEEK);
		if (error)
			goto bad;
		if (sio) {
			do {
				sbappend(sio, m);
				KKASSERT(resid >= (size_t)m->m_len);
				resid -= (size_t)m->m_len;
			} while (resid > 0 && m);
		} else {
			do {
				uio->uio_resid = resid;
				error = uiomove(mtod(m, caddr_t),
						(int)szmin(resid, m->m_len),
						uio);
				resid = uio->uio_resid;
				m = m_free(m);
			} while (uio->uio_resid && error == 0 && m);
		}
bad:
		if (m)
			m_freem(m);
		return (error);
	}
	if ((so->so_state & SS_ISCONFIRMING) && resid)
		so_pru_rcvd(so, 0);

	/*
	 * The token interlocks against the protocol thread while
	 * ssb_lock is a blocking lock against other userland entities.
	 */
	lwkt_gettoken(&so->so_rcv.ssb_token);
restart:
	error = ssb_lock(&so->so_rcv, SBLOCKWAIT(flags));
	if (error)
		goto done;

	m = so->so_rcv.ssb_mb;
	/*
	 * If we have less data than requested, block awaiting more
	 * (subject to any timeout) if:
	 *   1. the current count is less than the low water mark, or
	 *   2. MSG_WAITALL is set, and it is possible to do the entire
	 *	receive operation at once if we block (resid <= hiwat).
	 *   3. MSG_DONTWAIT is not set
	 * If MSG_WAITALL is set but resid is larger than the receive buffer,
	 * we have to do the receive in sections, and thus risk returning
	 * a short count if a timeout or signal occurs after we start.
	 */
	if (m == NULL || (((flags & MSG_DONTWAIT) == 0 &&
	    (size_t)so->so_rcv.ssb_cc < resid) &&
	    (so->so_rcv.ssb_cc < so->so_rcv.ssb_lowat ||
	    ((flags & MSG_WAITALL) && resid <= (size_t)so->so_rcv.ssb_hiwat)) &&
	    m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0)) {
		KASSERT(m != NULL || !so->so_rcv.ssb_cc, ("receive 1"));
		if (so->so_error) {
			if (m)
				goto dontblock;
			error = so->so_error;
			if ((flags & MSG_PEEK) == 0)
				so->so_error = 0;
			goto release;
		}
		if (so->so_state & SS_CANTRCVMORE) {
			if (m)
				goto dontblock;
			else
				goto release;
		}
		for (; m; m = m->m_next) {
			if (m->m_type == MT_OOBDATA  || (m->m_flags & M_EOR)) {
				m = so->so_rcv.ssb_mb;
				goto dontblock;
			}
		}
		if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
		    (pr->pr_flags & PR_CONNREQUIRED)) {
			error = ENOTCONN;
			goto release;
		}
		if (resid == 0)
			goto release;
		if (flags & (MSG_FNONBLOCKING|MSG_DONTWAIT)) {
			error = EWOULDBLOCK;
			goto release;
		}
		ssb_unlock(&so->so_rcv);
		error = ssb_wait(&so->so_rcv);
		if (error)
			goto done;
		goto restart;
	}
dontblock:
	if (uio && uio->uio_td && uio->uio_td->td_proc)
		uio->uio_td->td_lwp->lwp_ru.ru_msgrcv++;

	/*
	 * note: m should be == sb_mb here.  Cache the next record while
	 * cleaning up.  Note that calling m_free*() will break out critical
	 * section.
	 */
	KKASSERT(m == so->so_rcv.ssb_mb);

	/*
	 * Skip any address mbufs prepending the record.
	 */
	if (pr->pr_flags & PR_ADDR) {
		KASSERT(m->m_type == MT_SONAME, ("receive 1a"));
		orig_resid = 0;
		if (psa)
			*psa = dup_sockaddr(mtod(m, struct sockaddr *));
		if (flags & MSG_PEEK)
			m = m->m_next;
		else
			m = sbunlinkmbuf(&so->so_rcv.sb, m, &free_chain);
	}
Example #25
0
int
bootpc_call(
     struct bootp_packet *call,
     struct bootp_packet *reply,	/* output */
     struct proc *procp)
{
	struct socket *so;
	struct sockaddr_in *sin;
	struct mbuf *m, *nam;
	struct uio auio;
	struct iovec aio;
	int error, rcvflg, timo, secs, len;

	/* Free at end if not null. */
	nam = NULL;

	/*
	 * Create socket and set its recieve timeout.
	 */
	if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)))
		goto out;

	m = m_get(M_WAIT, MT_SOOPTS);
	if (m == NULL) {
		error = ENOBUFS;
		goto out;
	} else {
		struct timeval *tv;
		tv = mtod(m, struct timeval *);
		m->m_len = sizeof(*tv);
		tv->tv_sec = 1;
		tv->tv_usec = 0;
		if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m)))
			goto out;
	}

	/*
	 * Enable broadcast.
	 */
	{
		int *on;
		m = m_get(M_WAIT, MT_SOOPTS);
		if (m == NULL) {
			error = ENOBUFS;
			goto out;
		}
		on = mtod(m, int *);
		m->m_len = sizeof(*on);
		*on = 1;
		if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m)))
			goto out;
	}

	/*
	 * Bind the local endpoint to a bootp client port.
	 */
	m = m_getclr(M_WAIT, MT_SONAME);
	sin = mtod(m, struct sockaddr_in *);
	sin->sin_len = m->m_len = sizeof(*sin);
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = INADDR_ANY;
	sin->sin_port = htons(IPPORT_BOOTPC);
	error = sobind(so, m);
	m_freem(m);
	if (error) {
		printf("bind failed\n");
		goto out;
	}

	/*
	 * Setup socket address for the server.
	 */
	nam = m_get(M_WAIT, MT_SONAME);
	if (nam == NULL) {
		error = ENOBUFS;
		goto out;
	}
	sin = mtod(nam, struct sockaddr_in *);
	sin-> sin_len = sizeof(*sin);
	sin-> sin_family = AF_INET;
	sin->sin_addr.s_addr = INADDR_BROADCAST;
	sin->sin_port = htons(IPPORT_BOOTPS);

	nam->m_len = sizeof(*sin);

	/*
	 * Send it, repeatedly, until a reply is received,
	 * but delay each re-send by an increasing amount.
	 * If the delay hits the maximum, start complaining.
	 */
	for (timo=1; timo <= MAX_RESEND_DELAY; timo++) {
		/* Send BOOTP request (or re-send). */
		
		aio.iov_base = (caddr_t) call;
		aio.iov_len = sizeof(*call);
		
		auio.uio_iov = &aio;
		auio.uio_iovcnt = 1;
		auio.uio_segflg = UIO_SYSSPACE;
		auio.uio_rw = UIO_WRITE;
		auio.uio_offset = 0;
		auio.uio_resid = sizeof(*call);
		auio.uio_procp = procp;
		error = sosend(so, nam, &auio, NULL, NULL, 0);
		if (error) {
			printf("bootpc_call: sosend: %d\n", error);
                        switch (error) {
                        case  ENOBUFS:             /* No buffer space available */
                        case  ENETUNREACH:         /* Network is unreachable */
                        case  ENETDOWN:            /* Network interface is not configured */
                        case  EHOSTDOWN:           /* Host is down */
                        case  EHOSTUNREACH:        /* Host is unreachable */
                        case  EMSGSIZE:            /* Message too long */
                                /* This is a possibly transient error.
                                   We can still receive replies from previous attempts. */
                                break;
                        default:
                              goto out;
                        }
		}

		/*
		 * Wait for up to timo seconds for a reply.
		 * The socket receive timeout was set to 1 second.
		 */
		secs = timo;
		while (secs > 0) {
			aio.iov_base = (caddr_t) reply;
			aio.iov_len = sizeof(*reply);

			auio.uio_iov = &aio;
			auio.uio_iovcnt = 1;
			auio.uio_segflg = UIO_SYSSPACE;
			auio.uio_rw = UIO_READ;
			auio.uio_offset = 0;
			auio.uio_resid = sizeof(*reply);
			auio.uio_procp = procp;
			
			rcvflg = 0;
			error = soreceive(so, NULL, &auio, NULL, NULL, &rcvflg);
			if (error == EWOULDBLOCK) {
				secs--;
				call->secs=htons(ntohs(call->secs)+1);
				continue;
			}
			if (error)
				goto out;
			len = sizeof(*reply) - auio.uio_resid;

			/* Do we have the required number of bytes ? */
			if (len < BOOTP_MIN_LEN)
				continue;

			/* Is it the right reply? */
			if (reply->op != 2)
			  continue;

			if (reply->xid != call->xid)
				continue;

			if (reply->hlen != call->hlen)
			  continue;

			if (bcmp(reply->chaddr,call->chaddr,call->hlen))
			  continue;

			goto gotreply;	/* break two levels */

		} /* while secs */
	} /* send/receive a number of times then return an error */
	{
		uint32_t addr = ntohl(sin->sin_addr.s_addr);
        printf("BOOTP timeout for server %"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32"\n",
               (addr >> 24) & 0xff, (addr >> 16) & 0xff,
               (addr >> 8) & 0xff, addr & 0xff);
	}
	error = ETIMEDOUT;
	goto out;

 gotreply:
 out:
	if (nam) m_freem(nam);
	soclose(so);
	return error;
}
Example #26
0
int main(int argc, char ** argv) {

	// Keep track of the start time of the program
  long long program_start_time = get_time();
	
	// Let the user specify the number of frames to process
	int num_frames = 1;
	
	if (argc !=5){
		fprintf(stderr, "usage: %s <num of frames> <num of threads><input file>", argv[0]);
		exit(1);
	}
	
	if (argc > 1){
		num_frames = atoi(argv[1]);
		omp_num_threads = atoi(argv[2]);
		omp_num_threads2 = atoi(argv[3]);
		}
	printf("Num of threads: %d\n", omp_num_threads);
	printf("Num of threads: %d\n", omp_num_threads2);
	omp_set_nested(1);
	// Open video file
	char *video_file_name;
	video_file_name = argv[4];
	
	avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
	if (cell_file == NULL)	{
		AVI_print_error("Error with AVI_open_input_file");
		return -1;
	}
	
	int i, j, *crow, *ccol, pair_counter = 0, x_result_len = 0, Iter = 20, ns = 4, k_count = 0, n;
	MAT *cellx, *celly, *A;
	double *GICOV_spots, *t, *G, *x_result, *y_result, *V, *QAX_CENTERS, *QAY_CENTERS;
	double threshold = 1.8, radius = 10.0, delta = 3.0, dt = 0.01, b = 5.0;
	
	// Extract a cropped version of the first frame from the video file
	MAT *image_chopped = get_frame(cell_file, 0, 1, 0);
	printf("Detecting cells in frame 0\n");
	
	// Get gradient matrices in x and y directions
	MAT *grad_x = gradient_x(image_chopped);
	MAT *grad_y = gradient_y(image_chopped);
	
	m_free(image_chopped);
	
	// Get GICOV matrix corresponding to image gradients
	long long GICOV_start_time = get_time();
	MAT *gicov = ellipsematching(grad_x, grad_y);
	
	// Square GICOV values
	MAT *max_gicov = m_get(gicov->m, gicov->n);
	for (i = 0; i < gicov->m; i++) {
		for (j = 0; j < gicov->n; j++) {
			double val = m_get_val(gicov, i, j);
			m_set_val(max_gicov, i, j, val * val);
		}
	}
	
	long long GICOV_end_time = get_time();
	
	// Dilate the GICOV matrix
	long long dilate_start_time = get_time();
	MAT *strel = structuring_element(12);
	MAT *img_dilated = dilate_f(max_gicov, strel);
	long long dilate_end_time = get_time();
	
	// Find possible matches for cell centers based on GICOV and record the rows/columns in which they are found
	pair_counter = 0;
	crow = (int *) malloc(max_gicov->m * max_gicov->n * sizeof(int));
	ccol = (int *) malloc(max_gicov->m * max_gicov->n * sizeof(int));
	for (i = 0; i < max_gicov->m; i++) {
		for (j = 0; j < max_gicov->n; j++) {
			if (!(m_get_val(max_gicov,i,j) == 0.0) && (m_get_val(img_dilated,i,j) == m_get_val(max_gicov,i,j))) {
				crow[pair_counter] = i;
				ccol[pair_counter] = j;
				pair_counter++;
			}
		}
	}
	
	GICOV_spots = (double *) malloc(sizeof(double)*pair_counter);
	for (i = 0; i < pair_counter; i++)
		GICOV_spots[i] = m_get_val(gicov, crow[i], ccol[i]);
	
	G = (double *) calloc(pair_counter, sizeof(double));
	x_result = (double *) calloc(pair_counter, sizeof(double));
	y_result = (double *) calloc(pair_counter, sizeof(double));
	
	x_result_len = 0;
	for (i = 0; i < pair_counter; i++) {
		if ((crow[i] > 29) && (crow[i] < BOTTOM - TOP + 39)) {
			x_result[x_result_len] = ccol[i];
			y_result[x_result_len] = crow[i] - 40;
			G[x_result_len] = GICOV_spots[i];
			x_result_len++;
		}
	}
	
	// Make an array t which holds each "time step" for the possible cells
	t = (double *) malloc(sizeof(double) * 36);
	for (i = 0; i < 36; i++) {
		t[i] = (double)i * 2.0 * PI / 36.0;
	}
	
	// Store cell boundaries (as simple circles) for all cells
	cellx = m_get(x_result_len, 36);
	celly = m_get(x_result_len, 36);
	for(i = 0; i < x_result_len; i++) {
		for(j = 0; j < 36; j++) {
			m_set_val(cellx, i, j, x_result[i] + radius * cos(t[j]));
			m_set_val(celly, i, j, y_result[i] + radius * sin(t[j]));
		}
	}
	
	A = TMatrix(9,4);

	
	V = (double *) malloc(sizeof(double) * pair_counter);
	QAX_CENTERS = (double * )malloc(sizeof(double) * pair_counter);
	QAY_CENTERS = (double *) malloc(sizeof(double) * pair_counter);
	memset(V, 0, sizeof(double) * pair_counter);
	memset(QAX_CENTERS, 0, sizeof(double) * pair_counter);
	memset(QAY_CENTERS, 0, sizeof(double) * pair_counter);

	// For all possible results, find the ones that are feasibly leukocytes and store their centers
	k_count = 0;
	for (n = 0; n < x_result_len; n++) {
		if ((G[n] < -1 * threshold) || G[n] > threshold) {
			MAT * x, *y;
			VEC * x_row, * y_row;
			x = m_get(1, 36);
			y = m_get(1, 36);

			x_row = v_get(36);
			y_row = v_get(36);

			// Get current values of possible cells from cellx/celly matrices
			x_row = get_row(cellx, n, x_row);
			y_row = get_row(celly, n, y_row);
			uniformseg(x_row, y_row, x, y);

			// Make sure that the possible leukocytes are not too close to the edge of the frame
			if ((m_min(x) > b) && (m_min(y) > b) && (m_max(x) < cell_file->width - b) && (m_max(y) < cell_file->height - b)) {
				MAT * Cx, * Cy, *Cy_temp, * Ix1, * Iy1;
				VEC  *Xs, *Ys, *W, *Nx, *Ny, *X, *Y;
				Cx = m_get(1, 36);
				Cy = m_get(1, 36);
				Cx = mmtr_mlt(A, x, Cx);
				Cy = mmtr_mlt(A, y, Cy);
				
				Cy_temp = m_get(Cy->m, Cy->n);
				
				for (i = 0; i < 9; i++)
					m_set_val(Cy, i, 0, m_get_val(Cy, i, 0) + 40.0);
					
				// Iteratively refine the snake/spline
				for (i = 0; i < Iter; i++) {
					int typeofcell;
					
					if(G[n] > 0.0) typeofcell = 0;
					else typeofcell = 1;
					
					splineenergyform01(Cx, Cy, grad_x, grad_y, ns, delta, 2.0 * dt, typeofcell);
				}
				
				X = getsampling(Cx, ns);
				for (i = 0; i < Cy->m; i++)
					m_set_val(Cy_temp, i, 0, m_get_val(Cy, i, 0) - 40.0);
				Y = getsampling(Cy_temp, ns);
				
				Ix1 = linear_interp2(grad_x, X, Y);
				Iy1 = linear_interp2(grad_x, X, Y);
				Xs = getfdriv(Cx, ns);
				Ys = getfdriv(Cy, ns);
				
				Nx = v_get(Ys->dim);
				for (i = 0; i < Ys->dim; i++)
					v_set_val(Nx, i, v_get_val(Ys, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				Ny = v_get(Xs->dim);
				for (i = 0; i < Xs->dim; i++)
					v_set_val(Ny, i, -1.0 * v_get_val(Xs, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				W = v_get(Nx->dim);
				for (i = 0; i < Nx->dim; i++)
					v_set_val(W, i, m_get_val(Ix1, 0, i) * v_get_val(Nx, i) + m_get_val(Iy1, 0, i) * v_get_val(Ny, i));
					
				V[n] = mean(W) / std_dev(W);
				
				//get means of X and Y values for all "snaxels" of the spline contour, thus finding the cell centers
				QAX_CENTERS[k_count] = mean(X);
				QAY_CENTERS[k_count] = mean(Y) + TOP;
				
				k_count++;
				
				// Free memory
				v_free(W);
				v_free(Ny);
				v_free(Nx);
				v_free(Ys);
				v_free(Xs);
				m_free(Iy1);
				m_free(Ix1);
				v_free(Y);
				v_free(X);
				m_free(Cy_temp);
				m_free(Cy);
				m_free(Cx);				
			}
			
			// Free memory
			v_free(y_row);
			v_free(x_row);
			m_free(y);
			m_free(x);
		}
	}

	// Free memory
	free(V);
	free(ccol);
	free(crow);
	free(GICOV_spots);
	free(t);
	free(G);
	free(x_result);
	free(y_result);
	m_free(A);
	m_free(celly);
	m_free(cellx);
	m_free(img_dilated);
	m_free(max_gicov);
	m_free(gicov);
	m_free(grad_y);
	m_free(grad_x);
	
	// Report the total number of cells detected
	printf("Cells detected: %d\n\n", k_count);
	
	// Report the breakdown of the detection runtime
	printf("Detection runtime\n");
	printf("-----------------\n");
	printf("GICOV computation: %.5f seconds\n", ((float) (GICOV_end_time - GICOV_start_time)) / (1000*1000));
	printf("   GICOV dilation: %.5f seconds\n", ((float) (dilate_end_time - dilate_start_time)) / (1000*1000));
	printf("            Total: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
	
	// Now that the cells have been detected in the first frame,
	//  track the ellipses through subsequent frames
	if (num_frames > 1) printf("\nTracking cells across %d frames\n", num_frames);
	else                printf("\nTracking cells across 1 frame\n");
	long long tracking_start_time = get_time();
	int num_snaxels = 20;
	ellipsetrack(cell_file, QAX_CENTERS, QAY_CENTERS, k_count, radius, num_snaxels, num_frames);
	printf("           Total cambine: %.5f seconds\n", ((float) (get_time() - tracking_start_time)) / (float) (1000*1000*num_frames));
	
	// Report total program execution time
    printf("\nTotal application run time: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));

	return 0;
}
Example #27
0
/*
 * Peer has sent us a FIN.
 */
static int
do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
{
	struct adapter *sc = iq->adapter;
	const struct cpl_peer_close *cpl = (const void *)(rss + 1);
	unsigned int tid = GET_TID(cpl);
	struct toepcb *toep = lookup_tid(sc, tid);
	struct inpcb *inp = toep->inp;
	struct tcpcb *tp = NULL;
	struct socket *so;
	struct sockbuf *sb;
#ifdef INVARIANTS
	unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
#endif

	KASSERT(opcode == CPL_PEER_CLOSE,
	    ("%s: unexpected opcode 0x%x", __func__, opcode));
	KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));

	if (__predict_false(toep->flags & TPF_SYNQE)) {
#ifdef INVARIANTS
		struct synq_entry *synqe = (void *)toep;

		INP_WLOCK(synqe->lctx->inp);
		if (synqe->flags & TPF_SYNQE_HAS_L2TE) {
			KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN,
			    ("%s: listen socket closed but tid %u not aborted.",
			    __func__, tid));
		} else {
			/*
			 * do_pass_accept_req is still running and will
			 * eventually take care of this tid.
			 */
		}
		INP_WUNLOCK(synqe->lctx->inp);
#endif
		CTR4(KTR_CXGBE, "%s: tid %u, synqe %p (0x%x)", __func__, tid,
		    toep, toep->flags);
		return (0);
	}

	KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__));

	INP_INFO_WLOCK(&V_tcbinfo);
	INP_WLOCK(inp);
	tp = intotcpcb(inp);

	CTR5(KTR_CXGBE, "%s: tid %u (%s), toep_flags 0x%x, inp %p", __func__,
	    tid, tp ? tcpstates[tp->t_state] : "no tp", toep->flags, inp);

	if (toep->flags & TPF_ABORT_SHUTDOWN)
		goto done;

	tp->rcv_nxt++;	/* FIN */

	so = inp->inp_socket;
	sb = &so->so_rcv;
	SOCKBUF_LOCK(sb);
	if (__predict_false(toep->ddp_flags & (DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE))) {
		m = m_get(M_NOWAIT, MT_DATA);
		if (m == NULL)
			CXGBE_UNIMPLEMENTED("mbuf alloc failure");

		m->m_len = be32toh(cpl->rcv_nxt) - tp->rcv_nxt;
		m->m_flags |= M_DDP;	/* Data is already where it should be */
		m->m_data = "nothing to see here";
		tp->rcv_nxt = be32toh(cpl->rcv_nxt);

		toep->ddp_flags &= ~(DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE);

		KASSERT(toep->sb_cc >= sb->sb_cc,
		    ("%s: sb %p has more data (%d) than last time (%d).",
		    __func__, sb, sb->sb_cc, toep->sb_cc));
		toep->rx_credits += toep->sb_cc - sb->sb_cc;
#ifdef USE_DDP_RX_FLOW_CONTROL
		toep->rx_credits -= m->m_len;	/* adjust for F_RX_FC_DDP */
#endif
		sbappendstream_locked(sb, m);
		toep->sb_cc = sb->sb_cc;
	}
	socantrcvmore_locked(so);	/* unlocks the sockbuf */

	KASSERT(tp->rcv_nxt == be32toh(cpl->rcv_nxt),
	    ("%s: rcv_nxt mismatch: %u %u", __func__, tp->rcv_nxt,
	    be32toh(cpl->rcv_nxt)));

	switch (tp->t_state) {
	case TCPS_SYN_RECEIVED:
		tp->t_starttime = ticks;
		/* FALLTHROUGH */ 

	case TCPS_ESTABLISHED:
		tp->t_state = TCPS_CLOSE_WAIT;
		break;

	case TCPS_FIN_WAIT_1:
		tp->t_state = TCPS_CLOSING;
		break;

	case TCPS_FIN_WAIT_2:
		tcp_twstart(tp);
		INP_UNLOCK_ASSERT(inp);	 /* safe, we have a ref on the inp */
		INP_INFO_WUNLOCK(&V_tcbinfo);

		INP_WLOCK(inp);
		final_cpl_received(toep);
		return (0);

	default:
		log(LOG_ERR, "%s: TID %u received CPL_PEER_CLOSE in state %d\n",
		    __func__, tid, tp->t_state);
	}
done:
	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(&V_tcbinfo);
	return (0);
}
Example #28
0
void
icmp_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
           const char *message)
{
  unsigned hlen, shlen, s_ip_len;
  register struct ip *ip;
  register struct icmp *icp;
  register struct mbuf *m;

  DEBUG_CALL("icmp_send_error");
  DEBUG_ARG("msrc = %p", msrc);
  DEBUG_ARG("msrc_len = %d", msrc->m_len);

  if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error;

  /* check msrc */
  if(!msrc) goto end_error;
  ip = mtod(msrc, struct ip *);
#ifdef DEBUG
  { char bufa[20], bufb[20];
    strcpy(bufa, inet_ntoa(ip->ip_src));
    strcpy(bufb, inet_ntoa(ip->ip_dst));
    DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb));
  }
#endif
  if(ip->ip_off & IP_OFFMASK) goto end_error;    /* Only reply to fragment 0 */

  /* Do not reply to source-only IPs */
  if ((ip->ip_src.s_addr & htonl(~(0xf << 28))) == 0) {
      goto end_error;
  }

  shlen=ip->ip_hl << 2;
  s_ip_len=ip->ip_len;
  if(ip->ip_p == IPPROTO_ICMP) {
    icp = (struct icmp *)((char *)ip + shlen);
    /*
     *	Assume any unknown ICMP type is an error. This isn't
     *	specified by the RFC, but think about it..
     */
    if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error;
  }

  /* make a copy */
  m = m_get(msrc->slirp);
  if (!m) {
      goto end_error;
  }

  { int new_m_size;
    new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
    if(new_m_size>m->m_size) m_inc(m, new_m_size);
  }
  memcpy(m->m_data, msrc->m_data, msrc->m_len);
  m->m_len = msrc->m_len;                        /* copy msrc to m */

  /* make the header of the reply packet */
  ip  = mtod(m, struct ip *);
  hlen= sizeof(struct ip );     /* no options in reply */

  /* fill in icmp */
  m->m_data += hlen;
  m->m_len -= hlen;

  icp = mtod(m, struct icmp *);

  if(minsize) s_ip_len=shlen+ICMP_MINLEN;   /* return header+8b only */
  else if(s_ip_len>ICMP_MAXDATALEN)         /* maximum size */
    s_ip_len=ICMP_MAXDATALEN;

  m->m_len=ICMP_MINLEN+s_ip_len;        /* 8 bytes ICMP header */

  /* min. size = 8+sizeof(struct ip)+8 */

  icp->icmp_type = type;
  icp->icmp_code = code;
  icp->icmp_id = 0;
  icp->icmp_seq = 0;

  memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len);   /* report the ip packet */
  HTONS(icp->icmp_ip.ip_len);
  HTONS(icp->icmp_ip.ip_id);
  HTONS(icp->icmp_ip.ip_off);

#ifdef DEBUG
  if(message) {           /* DEBUG : append message to ICMP packet */
    int message_len;
    char *cpnt;
    message_len=strlen(message);
    if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN;
    cpnt=(char *)m->m_data+m->m_len;
    memcpy(cpnt, message, message_len);
    m->m_len+=message_len;
  }
#endif

  icp->icmp_cksum = 0;
  icp->icmp_cksum = cksum(m, m->m_len);

  m->m_data -= hlen;
  m->m_len += hlen;

  /* fill in ip */
  ip->ip_hl = hlen >> 2;
  ip->ip_len = m->m_len;

  ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0);  /* high priority for errors */

  ip->ip_ttl = MAXTTL;
  ip->ip_p = IPPROTO_ICMP;
  ip->ip_dst = ip->ip_src;    /* ip addresses */
  ip->ip_src = m->slirp->vhost_addr;

  (void ) ip_output((struct socket *)NULL, m);

end_error:
  return;
}
Example #29
0
/*
 * Make space for a new header of length hlen at skip bytes
 * into the packet.  When doing this we allocate new mbufs only
 * when absolutely necessary.  The mbuf where the new header
 * is to go is returned together with an offset into the mbuf.
 * If NULL is returned then the mbuf chain may have been modified;
 * the caller is assumed to always free the chain.
 */
struct mbuf *
m_makespace(struct mbuf *m0, int skip, int hlen, int *off)
{
	struct mbuf *m;
	unsigned remain;

	IPSEC_ASSERT(m0 != NULL, ("null mbuf"));
	IPSEC_ASSERT(hlen < MHLEN, ("hlen too big: %u", hlen));

	for (m = m0; m && skip > m->m_len; m = m->m_next)
		skip -= m->m_len;
	if (m == NULL)
		return (NULL);
	/*
	 * At this point skip is the offset into the mbuf m
	 * where the new header should be placed.  Figure out
	 * if there's space to insert the new header.  If so,
	 * and copying the remainder makes sense then do so.
	 * Otherwise insert a new mbuf in the chain, splitting
	 * the contents of m as needed.
	 */
	remain = m->m_len - skip;		/* data to move */
	if (hlen > M_TRAILINGSPACE(m)) {
		struct mbuf *n0, *n, **np;
		int todo, len, done, alloc;

		n0 = NULL;
		np = &n0;
		alloc = 0;
		done = 0;
		todo = remain;
		while (todo > 0) {
			if (todo > MHLEN) {
				n = m_getcl(M_NOWAIT, m->m_type, 0);
				len = MCLBYTES;
			}
			else {
				n = m_get(M_NOWAIT, m->m_type);
				len = MHLEN;
			}
			if (n == NULL) {
				m_freem(n0);
				return NULL;
			}
			*np = n;
			np = &n->m_next;
			alloc++;
			len = min(todo, len);
			memcpy(n->m_data, mtod(m, char *) + skip + done, len);
			n->m_len = len;
			done += len;
			todo -= len;
		}

		if (hlen <= M_TRAILINGSPACE(m) + remain) {
			m->m_len = skip + hlen;
			*off = skip;
			if (n0 != NULL) {
				*np = m->m_next;
				m->m_next = n0;
			}
		}
		else {
			n = m_get(M_NOWAIT, m->m_type);
			if (n == NULL) {
				m_freem(n0);
				return NULL;
			}
			alloc++;

			if ((n->m_next = n0) == NULL)
				np = &n->m_next;
			n0 = n;

			*np = m->m_next;
			m->m_next = n0;

			n->m_len = hlen;
			m->m_len = skip;

			m = n;			/* header is at front ... */
			*off = 0;		/* ... of new mbuf */
		}
		IPSECSTAT_INC(ips_mbinserted);
	} else {
Example #30
0
mitkIpInt4_t mitkIpFuncInertia ( mitkIpPicDescriptor *pic_old,
                         mitkIpFloat8_t     **eigen_vekt,
                         mitkIpFloat8_t     **eigen_val )            
{

  mitkIpUInt4_t       index_vect[_mitkIpPicNDIM]; /* loopindex-vector           */
  mitkIpInt4_t        n[_mitkIpPicNDIM];          /* number of pixels in each   */
                                          /* dimension                  */
  mitkIpUInt4_t       i, j;                   /* loop index                 */
  mitkIpFloat8_t      *gravity;               /* center of gravity          */
  mitkIpFloat8_t      *help_vekt;             /* pointer to eigen_vekt      */
  mitkIpFloat8_t      *help_val;              /* pointer to eigen_val       */
  MAT             *ev;                    /* eigenvector                */
  MAT             *tt;                    /* tensor of inertia          */
  VEC             *ew;                    /* eigenvalue                 */
  mitkIpFloat8_t      *s, *s_diag, *dist;     /* used to calculate tt       */

  /* check data  */

  if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR );
 
  /* initialisation of vectors  */

  for ( i = 0; i < pic_old->dim; i++ )
    n[i] = pic_old->n[i];
  
  for ( i = pic_old->dim; i < _mitkIpPicNDIM; i++ )
    n[i] = 1;

  for ( i = 0; i < _mitkIpPicNDIM; i++ )
    index_vect[i] = 0;

  /* memory allocation */

  gravity = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  if ( gravity == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       return ( mitkIpFuncERROR );
    }
 
  dist    = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  if ( dist == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       return ( mitkIpFuncERROR );
    }
 
  s_diag  = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  if ( s_diag == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       free ( dist );    
       return ( mitkIpFuncERROR );
    }
 
  s = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  if ( s == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       free ( dist );   
       free ( s_diag );
       return ( mitkIpFuncERROR );
    }
 
  tt = m_get ( pic_old->dim, pic_old->dim );
  if ( tt == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       free ( dist );   
       free ( s_diag );
       free ( s );
       return ( mitkIpFuncERROR );
    }

  ev = m_get ( pic_old->dim, pic_old->dim );
  if ( ev == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       free ( dist );   
       free ( s_diag );
       free ( s );
       M_FREE ( tt );
       return ( mitkIpFuncERROR );
    }

  ew = v_get ( pic_old->dim-1 );
  if ( ew == NULL ) 
    {
       _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR );
       free ( gravity );
       free ( dist );   
       free ( s_diag );
       free ( s );
       M_FREE ( tt );
       M_FREE ( ev );
       return ( mitkIpFuncERROR );
    }

  /* calculate center of gravity  */

  gravity = mitkIpFuncGrav ( pic_old );

  /* Initialization of vectors */

  for ( i = 0; i < pic_old->dim; i++ )
     {
        s_diag[i] = 0.;
        dist[i]   = 0.;
        for ( j = 0; j < pic_old->dim; j++ )
          s[i*pic_old->dim+j] = 0.;
     }

  /* preparation for calculating the tensor of inertia */

  mitkIpPicFORALL_4 ( GRAV, pic_old, index_vect, s, s_diag, dist ) 

  /* calculate tensor of inertia  */

  for ( i = 0; i < pic_old->dim; i++ )
    {
       tt->me[i][i] = 0.;
       for ( j = 0; j < pic_old->dim; j++ )
         {
            if ( i < j )
               tt->me[i][j] = s[i*pic_old->dim+j];
            else if ( j < i )
               tt->me[i][j] = s[j*pic_old->dim+i];
            if ( i != j ) 
               tt->me[i][i] = tt->me[i][i] + s_diag[j];
         }
    }

  /* calculate eigenvectors and eigenvalues of the tensor of inertia */

  ew = symmeig ( tt, ev, ew );

  *eigen_vekt = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  help_vekt   = *eigen_vekt;
  *eigen_val  = ( mitkIpFloat8_t * ) malloc ( pic_old->dim * sizeof ( mitkIpFloat8_t ) );
  help_val    = *eigen_val;

  for ( i = 0; i < pic_old->dim; i++ )
    {
      help_val[i] = ew->ve[i];
      for ( j = 0; j < pic_old->dim; j++ )
        help_vekt[i*pic_old->dim+j] = ev->me[i][j];
    }

  M_FREE ( tt );
  M_FREE ( ev );
  V_FREE ( ew );
  free ( s );
  free ( dist );
  free ( s_diag );
  free ( gravity );

  return mitkIpFuncOK;   
}