示例#1
0
  void LrDpleToDple::init() {
    // Initialize the base classes
    LrDpleInternal::init();

    MX As = MX::sym("As", input(LR_DPLE_A).sparsity());
    MX Vs = MX::sym("Vs", input(LR_DPLE_V).sparsity());
    MX Cs = MX::sym("Cs", input(LR_DPLE_C).sparsity());
    MX Hs = MX::sym("Hs", input(LR_DPLE_H).sparsity());

    int n_ = A_[0].size1();

    // Chop-up the arguments
    std::vector<MX> As_ = horzsplit(As, n_);
    std::vector<MX> Vs_ = horzsplit(Vs, V_[0].size2());
    std::vector<MX> Cs_ = horzsplit(Cs, V_[0].size2());
    std::vector<MX> Hss_ = horzsplit(Hs, Hsi_);

    std::vector<MX> V_(Vs_.size());

    for (int k=0;k<V_.size();++k) {
      V_[k] = mul(Cs_[k], mul(Vs_[k], Cs_[k].T()));
    }

    std::vector<Sparsity> Vsp(Vs_.size());
    for (int k=0;k<V_.size();++k) {
      Vsp[k] = V_[k].sparsity();
    }

    // Solver options
    Dict options;
    if (hasSetOption(optionsname())) {
      options = getOption(optionsname());
    }

    // Create an dplesolver instance
    std::map<std::string, std::vector<Sparsity> > tmp;
    tmp["a"] = A_;
    tmp["v"] = Vsp;
    solver_ = DpleSolver("solver", getOption(solvername()), tmp, options);

    MX P = solver_(make_map("a", horzcat(As_), "v", horzcat(V_))).at("p");
    std::vector<MX> Ps_ = horzsplit(P, n_);

    std::vector<MX> HPH(K_);

    for (int k=0;k<K_;++k) {
      std::vector<MX> hph = horzsplit(Hss_[k], cumsum0(Hs_[k]));

      for (int kk=0;kk<hph.size();++kk) {
        hph[kk] = mul(hph[kk].T(), mul(Ps_[k], hph[kk]));
      }
      HPH[k] = diagcat(hph);
    }


    f_ = MXFunction(name_, lrdpleIn("a", As, "v", Vs, "c", Cs, "h", Hs),
                    lrdpleOut("y", horzcat(HPH)));

    Wrapper<LrDpleToDple>::checkDimensions();
  }
  void FixedSmithLrDleInternal::init() {
    iter_  = getOption("iter");

    LrDleInternal::init();

    casadi_assert_message(!pos_def_,
      "pos_def option set to True: Solver only handles the indefinite case.");

    MX H = MX::sym("H", H_);
    MX A = MX::sym("A", A_);
    MX C = MX::sym("C", C_);
    MX V = MX::sym("V", V_);

    MX Vs = (V+V.T())/2;

    MX D = with_C_ ? C : DMatrix::eye(A_.size1());


    std::vector<MX> HPH(Hs_.size(), 0);
    std::vector<MX> Hs = with_H_? horzsplit(H, Hi_) : std::vector<MX>();
    MX out = 0;

    for (int i=0;i<iter_;++i) {
      if (with_H_) {
        for (int k=0;k<Hs.size();++k) {
          MX v = mul(D.T(), Hs[k]);
          HPH[k]+= mul(v.T(), mul(Vs, v));
        }
      } else {
        out += mul(D, mul(Vs, D.T()));
      }
      D = mul(A, D);
    }

    std::vector<MX> dle_in(LR_DLE_NUM_IN);
    dle_in[LR_DLE_A] = A;
    dle_in[LR_DLE_V] = V;
    if (with_C_) dle_in[LR_DLE_C] = C;
    if (with_H_) dle_in[LR_DLE_H] = H;

    f_ = MXFunction(dle_in, lrdleOut("y", with_H_? diagcat(HPH): out));
    f_.init();

    Wrapper<FixedSmithLrDleInternal>::checkDimensions();

  }
示例#3
0
inline 
#endif
int pcapProcess(sHeaderPacket **header_packet, int pushToStack_queue_index,
		pcap_block_store *block_store, int block_store_index,
		int ppf,
		pcapProcessData *ppd, int pcapLinklayerHeaderType, pcap_dumper_t *pcapDumpHandle, const char *interfaceName) {
 
	pcap_pkthdr_plus2 *pcap_header_plus2 = NULL;
	u_char *packet = NULL;
	if(header_packet) {
		if((*header_packet)->detect_headers & 0x01) {
			ppd->header_ip_offset = (*header_packet)->header_ip_first_offset;
			ppd->protocol = (*header_packet)->eth_protocol;
			ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset);
		} else if(parseEtherHeader(pcapLinklayerHeaderType, HPP(*header_packet),
					   ppd->header_sll, ppd->header_eth, ppd->header_ip_offset, ppd->protocol)) {
			(*header_packet)->detect_headers |= 0x01;
			(*header_packet)->header_ip_first_offset = ppd->header_ip_offset;
			(*header_packet)->eth_protocol = ppd->protocol;
			if(ppd->protocol != ETHERTYPE_IP) {
				if(sverb.tcpreplay) {
					if(ppd->protocol == 0) {
						ppd->header_ip_offset += 2;
						ppd->protocol = ETHERTYPE_IP;
					} else {
						return(0);
					}
				} else {
					pcapProcessEvalError(bad_eth_protocol, *HPH(*header_packet), HPP(*header_packet),
							     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
					return(0);
				}
			}
			ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset);
			if(ppd->header_ip->version != 4) {
				pcapProcessEvalError(bad_ip_version, *HPH(*header_packet), HPP(*header_packet),
						     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
				return(0);
			}
			if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > HPH(*header_packet)->len) {
				pcapProcessEvalError(bad_ip_length, *HPH(*header_packet), HPP(*header_packet),
						     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
				return(0);
			}
		} else {
			pcapProcessEvalError(bad_datalink, *HPH(*header_packet), HPP(*header_packet),
					     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
			return(0);
		}
	} else {
		pcap_header_plus2 = (pcap_pkthdr_plus2*)block_store->get_header(block_store_index);
		packet = block_store->get_packet(block_store_index);
		if(pcap_header_plus2->detect_headers & 0x01) {
			ppd->header_ip_offset = pcap_header_plus2->header_ip_first_offset;
			ppd->protocol = pcap_header_plus2->eth_protocol;
			ppd->header_ip = (iphdr2*)(packet + ppd->header_ip_offset);
		} else if(parseEtherHeader(pcapLinklayerHeaderType, packet,
					   ppd->header_sll, ppd->header_eth, ppd->header_ip_offset, ppd->protocol)) {
			pcap_header_plus2->detect_headers |= 0x01;
			pcap_header_plus2->header_ip_first_offset = ppd->header_ip_offset;
			pcap_header_plus2->eth_protocol = ppd->protocol;
			if(ppd->protocol != ETHERTYPE_IP) {
				if(sverb.tcpreplay) {
					if(ppd->protocol == 0) {
						ppd->header_ip_offset += 2;
						ppd->protocol = ETHERTYPE_IP;
					} else {
						pcap_header_plus2->ignore = true;
						return(0);
					}
				} else {
					pcapProcessEvalError(bad_eth_protocol, pcap_header_plus2, packet,
							     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
					pcap_header_plus2->ignore = true;
					return(0);
				}
			}
			ppd->header_ip = (iphdr2*)(packet + ppd->header_ip_offset);
			if(ppd->header_ip->version != 4) {
				pcapProcessEvalError(bad_ip_version, pcap_header_plus2, packet,
						     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
				pcap_header_plus2->ignore = true;
				return(0);
			}
			if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > pcap_header_plus2->get_len()) {
				pcapProcessEvalError(bad_ip_length, pcap_header_plus2, packet,
						     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
				pcap_header_plus2->ignore = true;
				return(0);
			}
		} else {
			pcapProcessEvalError(bad_datalink, pcap_header_plus2, packet,
					     ppd, pcapLinklayerHeaderType, pcapDumpHandle, interfaceName);
			pcap_header_plus2->ignore = true;
			return(0);
		}
	}
	
	if(ppf & ppf_defrag) {
		//if UDP defrag is enabled process only UDP packets and only SIP packets
		if(opt_udpfrag) {
			int foffset = ntohs(ppd->header_ip->frag_off);
			if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) {
				if(htons(ppd->header_ip->tot_len) + ppd->header_ip_offset > HPH(*header_packet)->caplen) {
					if(interfaceName) {
						extern BogusDumper *bogusDumper;
						static u_long lastTimeLogErrBadIpHeader = 0;
						if(bogusDumper) {
							bogusDumper->dump(HPH(*header_packet), HPP(*header_packet), pcapLinklayerHeaderType, interfaceName);
						}
						u_long actTime = getTimeMS(HPH(*header_packet));
						if(actTime - 1000 > lastTimeLogErrBadIpHeader) {
							syslog(LOG_ERR, "BAD FRAGMENTED HEADER_IP: %s: bogus ip header length %i, caplen %i", interfaceName, htons(ppd->header_ip->tot_len), HPH(*header_packet)->caplen);
							lastTimeLogErrBadIpHeader = actTime;
						}
					}
					//cout << "pcapProcess exit 001" << endl;
					return(0);
				}
				// packet is fragmented
				if(handle_defrag(ppd->header_ip, header_packet, &ppd->ipfrag_data, pushToStack_queue_index) > 0) {
					// packets are reassembled
					ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset);
					if(sverb.defrag) {
						defrag_counter++;
						cout << "*** DEFRAG 1 " << defrag_counter << endl;
					}
				} else {
					//cout << "pcapProcess exit 002" << endl;
					return(0);
				}
			}
		}
	}
	
	bool nextPass;
	do {
		nextPass = false;
		u_int first_header_ip_offset = ppd->header_ip_offset;
		if(ppd->header_ip->protocol == IPPROTO_IPIP) {
			// ip in ip protocol
			ppd->header_ip = (iphdr2*)((char*)ppd->header_ip + sizeof(iphdr2));
			ppd->header_ip_offset += sizeof(iphdr2);
		} else if(ppd->header_ip->protocol == IPPROTO_GRE) {
			// gre protocol
			iphdr2 *header_ip = convertHeaderIP_GRE(ppd->header_ip);
			if(header_ip) {
				ppd->header_ip = header_ip;
				ppd->header_ip_offset = (u_char*)header_ip - (header_packet ? HPP(*header_packet) : packet);
				nextPass = true;
			} else {
				if(ppf & ppf_returnZeroInCheckData) {
					//cout << "pcapProcess exit 004" << endl;
					if(pcap_header_plus2) {
						pcap_header_plus2->ignore = true;
					}
					return(0);
				}
			}
		} else {
			break;
		}
		if(ppf & ppf_defrag) {
			//if UDP defrag is enabled process only UDP packets and only SIP packets
			if(opt_udpfrag && ppd->header_ip->protocol == IPPROTO_UDP) {
				int foffset = ntohs(ppd->header_ip->frag_off);
				if ((foffset & IP_MF) || ((foffset & IP_OFFSET) > 0)) {
					// packet is fragmented
					if(handle_defrag(ppd->header_ip, header_packet, &ppd->ipfrag_data, pushToStack_queue_index) > 0) {
						// packets are reassembled
						iphdr2 *first_header_ip = (iphdr2*)(HPP(*header_packet) + first_header_ip_offset);

						// turn off frag flag in the first IP header
						first_header_ip->frag_off = 0;

						// turn off frag flag in the second IP header
						ppd->header_ip = (iphdr2*)(HPP(*header_packet) + ppd->header_ip_offset);
						ppd->header_ip->frag_off = 0;

						// update lenght of the first ip header to the len of the second IP header since it can be changed due to reassemble
						first_header_ip->tot_len = htons(ntohs(ppd->header_ip->tot_len) + (ppd->header_ip_offset - first_header_ip_offset));

						if(sverb.defrag) {
							defrag_counter++;
							cout << "*** DEFRAG 2 " << defrag_counter << endl;
						}
					} else {
						//cout << "pcapProcess exit 003" << endl;
						return(0);
					}
				}
			}
		}
	} while(nextPass);
	
	if(header_packet) {
		(*header_packet)->header_ip_offset = ppd->header_ip_offset;
	} else {
		pcap_header_plus2->header_ip_offset = ppd->header_ip_offset;
	}
	
	if(ppf & ppf_defrag) {
		// if IP defrag is enabled, run each 10 seconds cleaning 
		if(opt_udpfrag && (ppd->ipfrag_lastprune + 10) < HPH(*header_packet)->ts.tv_sec) {
			ipfrag_prune(HPH(*header_packet)->ts.tv_sec, false, &ppd->ipfrag_data, pushToStack_queue_index, -1);
			ppd->ipfrag_lastprune = HPH(*header_packet)->ts.tv_sec;
			//TODO it would be good to still pass fragmented packets even it does not contain the last semant, the ipgrad_prune just wipes all unfinished frags
		}
	}
	
	if(!(ppf & ppf_defragInPQout)) {
		u_int32_t caplen;
		if(header_packet) {
			caplen = HPH(*header_packet)->caplen;
			packet = HPP(*header_packet);
		} else {
			caplen = pcap_header_plus2->get_caplen();
		}
		ppd->header_udp = &ppd->header_udp_tmp;
		if (ppd->header_ip->protocol == IPPROTO_UDP) {
			// prepare packet pointers 
			ppd->header_udp = (udphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip));
			ppd->data = (char*) ppd->header_udp + sizeof(*ppd->header_udp);
			ppd->datalen = (int)(caplen - ((u_char*)ppd->data - packet)); 
			ppd->traillen = (int)(caplen - ((u_char*)ppd->header_ip - packet)) - ntohs(ppd->header_ip->tot_len);
			ppd->istcp = 0;
		} else if (ppd->header_ip->protocol == IPPROTO_TCP) {
			ppd->istcp = 1;
			// prepare packet pointers 
			ppd->header_tcp = (tcphdr2*) ((char*) ppd->header_ip + sizeof(*ppd->header_ip));
			ppd->data = (char*) ppd->header_tcp + (ppd->header_tcp->doff * 4);
			ppd->datalen = (int)(caplen - ((u_char*)ppd->data - packet)); 
			if (!(sipportmatrix[htons(ppd->header_tcp->source)] || sipportmatrix[htons(ppd->header_tcp->dest)]) &&
			    !(opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)]) &&
			      (tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyHttp->check_ip(htonl(ppd->header_ip->daddr)))) &&
			    !(opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)]) &&
			      (tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->saddr)) || tcpReassemblyWebrtc->check_ip(htonl(ppd->header_ip->daddr)))) &&
			    !(opt_enable_ssl && 
			      (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) ||
			       isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest)))) &&
			    !(opt_skinny && (htons(ppd->header_tcp->source) == 2000 || htons(ppd->header_tcp->dest) == 2000))) {
				// not interested in TCP packet other than SIP port
				if(!opt_ipaccount && !DEBUG_ALL_PACKETS && (ppf & ppf_returnZeroInCheckData)) {
					//cout << "pcapProcess exit 005" << endl;
					if(pcap_header_plus2) {
						pcap_header_plus2->ignore = true;
					}
					return(0);
				}
			}

			ppd->header_udp->source = ppd->header_tcp->source;
			ppd->header_udp->dest = ppd->header_tcp->dest;
		} else {
			//packet is not UDP and is not TCP, we are not interested, go to the next packet (but if ipaccount is enabled, do not skip IP
			ppd->datalen = 0;
			if(!opt_ipaccount && !DEBUG_ALL_PACKETS && (ppf & ppf_returnZeroInCheckData)) {
				//cout << "pcapProcess exit 006 / protocol: " << (int)ppd->header_ip->protocol << endl;
				if(pcap_header_plus2) {
					pcap_header_plus2->ignore = true;
				}
				return(0);
			}
		}

		if(ppd->datalen < 0 && (ppf & ppf_returnZeroInCheckData)) {
			//cout << "pcapProcess exit 007" << endl;
			if(pcap_header_plus2) {
				pcap_header_plus2->ignore = true;
			}
			return(0);
		}
	} else {
		ppd->data = NULL;
		ppd->datalen = 0;
	}

	if((ppf & ppf_calcMD5) || (ppf & ppf_dedup)) {
		// check for duplicate packets (md5 is expensive operation - enable only if you really need it
		if(opt_dup_check && 
		   ppd->prevmd5s != NULL && 
		   ((ppf & ppf_defragInPQout) ||
		    (ppd->datalen > 0 && (opt_dup_check_ipheader || ppd->traillen < ppd->datalen))) &&
		   !(ppd->istcp && opt_enable_http && (httpportmatrix[htons(ppd->header_tcp->source)] || httpportmatrix[htons(ppd->header_tcp->dest)])) &&
		   !(ppd->istcp && opt_enable_webrtc && (webrtcportmatrix[htons(ppd->header_tcp->source)] || webrtcportmatrix[htons(ppd->header_tcp->dest)])) &&
		   !(ppd->istcp && opt_enable_ssl && (isSslIpPort(htonl(ppd->header_ip->saddr), htons(ppd->header_tcp->source)) || isSslIpPort(htonl(ppd->header_ip->daddr), htons(ppd->header_tcp->dest))))) {
			uint16_t *_md5 = header_packet ? (*header_packet)->md5 : pcap_header_plus2->md5;
			if(ppf & ppf_calcMD5) {
				MD5_Init(&ppd->ctx);
				if(ppf & ppf_defragInPQout) {
					u_int32_t caplen = header_packet ? HPH(*header_packet)->caplen : pcap_header_plus2->get_caplen();
					MD5_Update(&ppd->ctx, ppd->header_ip, MIN(caplen - ppd->header_ip_offset, ntohs(ppd->header_ip->tot_len)));
				} else if(opt_dup_check_ipheader) {
					MD5_Update(&ppd->ctx, ppd->header_ip, MIN(ppd->datalen + (ppd->data - (char*)ppd->header_ip), ntohs(ppd->header_ip->tot_len)));
				} else {
					// check duplicates based only on data (without ip header and without UDP/TCP header). Duplicate packets 
					// will be matched regardless on IP 
					MD5_Update(&ppd->ctx, ppd->data, MAX(0, (unsigned long)ppd->datalen - ppd->traillen));
				}
				MD5_Final((unsigned char*)_md5, &ppd->ctx);
			}
			if((ppf & ppf_dedup) && _md5[0]) {
				if(memcmp(_md5, ppd->prevmd5s + (_md5[0] * MD5_DIGEST_LENGTH), MD5_DIGEST_LENGTH) == 0) {
					//printf("dropping duplicate md5[%s]\n", md5);
					duplicate_counter++;
					if(sverb.dedup) {
						cout << "*** DEDUP " << duplicate_counter << endl;
					}
					if(pcap_header_plus2) {
						pcap_header_plus2->ignore = true;
					}
					return(0);
				}
				memcpy(ppd->prevmd5s + (_md5[0] * MD5_DIGEST_LENGTH), _md5, MD5_DIGEST_LENGTH);
			}
		}
	}
	
	if(ppf & ppf_dump) {
		if(pcapDumpHandle) {
			if(header_packet) {
				pcap_dump((u_char*)pcapDumpHandle, HPH(*header_packet), HPP(*header_packet));
			} else {
				pcap_pkthdr header = pcap_header_plus2->getStdHeader();
				pcap_dump((u_char*)pcapDumpHandle, &header, packet);
			}
		}
	}
	
	return(1);
}