/* * 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; }
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); }
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); }
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); }
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); }
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); }
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; }
/* * 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); }
/* * 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, ¤t_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); }
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; }
/* * 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); }
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; }
/* * 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; }
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);
/*{{{ 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; }
/* 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; }
/* * 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); }
/* * 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; }
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); }
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); }
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)); }
/* * 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 */ }
/* * 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 = ⊤ 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 = ⊤ 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); }
/* * 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); }
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; }
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; }
/* * 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); }
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; }
/* * 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 {
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; }