Beispiel #1
0
int 
handle_snmp_event(struct oflops_context * ctx, struct snmp_event * se) {
  netsnmp_variable_list *vars;
  int len = 1024;
  char msg[1024], log[1024];
  struct timeval now;
  int i;
  gettimeofday(&now, NULL);

  for(vars = se->pdu->variables; vars; vars = vars->next_variable)  {
    snprint_value(msg, len, vars->name, vars->name_length, vars);
    if((vars->name_length == ctx->cpuOID_len) &&
       (memcmp(vars->name, ctx->cpuOID,  ctx->cpuOID_len * sizeof(oid)) == 0) ) {
      snprintf(log, len, "cpu : %s %%", msg);
      oflops_log(now, SNMP_MSG, log);
    } else {
      for(i=0;i<ctx->n_channels;i++) {
	if((vars->name_length == ctx->channels[i].inOID_len) &&
	   (memcmp(vars->name, ctx->channels[i].inOID,  
		   ctx->channels[i].inOID_len * sizeof(oid)) == 0) ) {
	  snprintf(log, len, "port %d : rx %s pkts",  
		   (int)ctx->channels[i].outOID[ctx->channels[i].outOID_len-1], msg);
	  oflops_log(now, SNMP_MSG, log);
	  break;
	}
	
	if((vars->name_length == ctx->channels[i].outOID_len) &&
	   (memcmp(vars->name, ctx->channels[i].outOID,  
		   ctx->channels[i].outOID_len * sizeof(oid))==0) ) {
	  snprintf(log, len, "port %d : tx %s pkts",  
		   (int)ctx->channels[i].outOID[ctx->channels[i].outOID_len-1], msg);
	  oflops_log(now, SNMP_MSG, log);
	  break;
	}
      } //for
    }// if cpu
  }// variable iterator
  return 0;
}
Beispiel #2
0
/** Handle pcap event.
 * @param ctx pointer to opaque context
 * @param pe pcap event
 * @param ch enumeration of channel that pcap event is triggered
 */
int 
handle_pcap_event(struct oflops_context *ctx, struct pcap_event * pe, oflops_channel_name ch) {
  struct pktgen_hdr *pktgen;
  int dir, len;
  struct ofp_header *ofp;
  struct pcap_event *ofp_msg;
  struct ofp_error_msg *err_p = NULL;
  char msg[1024];

  if (ch == OFLOPS_CONTROL) {
    dir = append_data_to_flow(pe->data,pe->pcaphdr);
    while(contains_next_msg(dir) > 0) {
      len = get_next_msg(dir, &ofp_msg);
      ofp = (struct ofp_header *)ofp_msg->data;
      switch(ofp->type) {
      case OFPT_FLOW_MOD:
	if (send_false_mod) {
	  if(send_mod) {
	    memcpy(&true_modification, &pe->pcaphdr.ts, sizeof(struct timeval));
	  } else {
	    memcpy(&false_modification, &pe->pcaphdr.ts, sizeof(struct timeval));
	  }
	}
	if(send_mod) {
	  oflops_log(pe->pcaphdr.ts,OFPT_FLOW_MOD_ADD, "flow modification send");
	}
	break;
      case OFPT_ECHO_REQUEST:
	if(ntohl(ofp->xid) < 100) 
	  memcpy(&ofp_ping_timestamp[ntohl(ofp->xid)], &pe->pcaphdr.ts, sizeof(struct timeval));
	break;
      case OFPT_ECHO_REPLY:
	if(ntohl(ofp->xid) < 100 && ntohl(ofp->xid) > 0) {
	  delay[ntohl(ofp->xid)] = time_diff(&ofp_ping_timestamp[ntohl(ofp->xid)], &pe->pcaphdr.ts);
	  snprintf(msg, 1024, "%d", time_diff(&ofp_ping_timestamp[ntohl(ofp->xid)], &pe->pcaphdr.ts));
	  oflops_log(pe->pcaphdr.ts, OFPT_ECHO_REPLY_MSG, msg);
	}
	break;    
      case OFPT_ERROR:
	err_p = (struct ofp_error_msg *)ofp;
	if(send_false_mod)  {
	  delay_false_modificaton = time_diff(&false_modification, &pe->pcaphdr.ts);
	} else {
	  snprintf(msg, 1024, "%d:%d", ntohs(err_p->type), ntohs(err_p->code));
	  oflops_log(pe->pcaphdr.ts, OFPT_ERROR_MSG, msg);
	  fprintf(stderr, "OFPT_ERROR_MSG:%s\n", msg);
	  break;   
	}
      }
    }
  } else if ((ch == OFLOPS_DATA1) || (ch == OFLOPS_DATA2) || (ch == OFLOPS_DATA3)) {
    struct flow fl;
    pktgen = extract_pktgen_pkt(pe->data, pe->pcaphdr.caplen, &fl);
    if((ch == OFLOPS_DATA3) && (!first_pkt)) {
      delay_modificaton = time_diff(&true_modification, &pe->pcaphdr.ts);
      oflops_log(pe->pcaphdr.ts, GENERIC_MSG, "first packet on new port");
      first_pkt = 1;
    }
    if(htonl(pktgen->seq_num) % 100000 == 0)
      printf("data packet received %d\n", htonl(pktgen->seq_num));
    
    struct entry *n1 = malloc(sizeof(struct entry));
    n1->snd.tv_sec = htonl(pktgen->tv_sec);
    n1->snd.tv_usec = htonl(pktgen->tv_usec);
    memcpy(&n1->rcv, &pe->pcaphdr.ts, sizeof(struct timeval));
    n1->id = htonl(pktgen->seq_num);
    n1->ch = ch;
    TAILQ_INSERT_TAIL(&head, n1, entries);
  }
  return 0;
}
Beispiel #3
0
/** Initialization
 * @param ctx pointer to opaque context
 */
int 
start(struct oflops_context * ctx) {  
  struct flow *fl = (struct flow*)xmalloc(sizeof(struct flow));
  fl_probe = (struct flow*)xmalloc(sizeof(struct flow));
  void *b; //somewhere to store message data
  int res, len, i;
  struct timeval now;
  struct in_addr ip_addr;

  //init measurement queue
  TAILQ_INIT(&head); 

  //init logging service
  msg_init();

  //log when I start module
  gettimeofday(&now, NULL);
  oflops_log(now,GENERIC_MSG , "Intializing module openflow_action_measurement");
  oflops_log(now,GENERIC_MSG , cli_param);

  //make filedescriptor blocking
  int saved_flags = fcntl(ctx->control_fd, F_GETFL);
  fcntl(ctx->control_fd, F_SETFL, saved_flags & ~O_NONBLOCK);


  make_ofp_hello(&b);
  //res = oflops_send_of_mesgs(ctx, b, sizeof(struct ofp_hello));
  res = write(ctx->control_fd, b, sizeof(struct ofp_hello));
  free(b);  

  // send a feature request to see what the switch can do and os that the connection
  // is kept open.
  make_ofp_feat_req(&b);
  //res = oflops_send_of_mesgs(ctx, b, sizeof(struct ofp_hello));
  res = write(ctx->control_fd, b, sizeof(struct ofp_hello));
  free(b);
  
  //send a message to clean up flow tables. 
  printf("cleaning up flow table...\n");
  res = make_ofp_flow_del(&b);
  res = write(ctx->control_fd, b, res);
  free(b);
  
  /**
   * Send flow records to start routing packets.
   */
  printf("Sending new flow rules...\n");
  bzero(fl, sizeof(struct flow));
  printf("table value:%d\n", table);
  if(table == 0) 
     fl->mask = 0; //if table is 0 the we generate an exact match */
  else  
    fl->mask = OFPFW_IN_PORT | OFPFW_DL_VLAN | OFPFW_TP_DST;
  fl->in_port = htons(ctx->channels[OFLOPS_DATA2].of_port);
  fl->dl_type = htons(ETHERTYPE_IP);          
  fl->dl_src[0] = 00; 
  fl->dl_src[1] = 0x1e; 
  fl->dl_src[2] = 0x68; 
  fl->dl_src[3] = 0x9a; 
  fl->dl_src[4] = 0xc5; 
  fl->dl_src[5] = 0x75; 
  fl->dl_dst[0] = 00; 
  fl->dl_dst[1] = 0x15; 
  fl->dl_dst[2] = 0x17; 
  fl->dl_dst[3] = 0x7b; 
  fl->dl_dst[4] = 0x92; 
  fl->dl_dst[5] = 0x0a; 
  fl->dl_vlan = 0xffff;
  fl->nw_proto = IPPROTO_UDP;
  fl->nw_src =  inet_addr("10.1.1.1");
  fl->nw_dst =  inet_addr("10.1.1.2");
  fl->tp_src = htons(8080);            
  fl->tp_dst = htons(8080);  
  len = make_ofp_flow_add(&b, fl, ctx->channels[OFLOPS_DATA1].of_port, 1, 1200);
  res = write(ctx->control_fd, b, len);
  free(b);
  
  //storelocally the applied rule of the data stream
  memcpy(fl_probe, fl, sizeof(struct flow));

  ip_addr.s_addr = inet_addr(network);
  ip_addr.s_addr =  ntohl(ip_addr.s_addr);
  fl->in_port = htons(ctx->channels[OFLOPS_DATA1].of_port);
  fl->dl_vlan = 0xffff;
  fl->dl_src[5] = 0x74;  
  fl->dl_dst[0] = 00; 
  fl->dl_dst[1] = 0x1e; 
  fl->dl_dst[2] = 0x68; 
  fl->dl_dst[3] = 0x9a; 
  fl->dl_dst[4] = 0xc5; 
  fl->dl_dst[5] = 0x75;
  fl->mask = 0;
  for(i=0; i< flows; i++) {
    ip_addr.s_addr += 1;
    fl->nw_dst =  htonl(ip_addr.s_addr);
    len = make_ofp_flow_add(&b, fl, ctx->channels[OFLOPS_DATA2].of_port, 1, 1200);
    res = write(ctx->control_fd, b, len);
    free(b);
  }
  
  len = make_ofp_port_get_stat(&b);
  free(b);

  saved_flags = fcntl(ctx->control_fd, F_GETFL);
  fcntl(ctx->control_fd, F_SETFL, saved_flags & O_NONBLOCK);

  /**
   * Shceduling events
   */
  //SND_FALSE_ACT
  gettimeofday(&now, NULL);
  add_time(&now, 20, 0);
  oflops_schedule_timer_event(ctx,&now, SND_FALSE_ACT);


  //send the flow modyfication command in 30 seconds. 
  gettimeofday(&now, NULL);
  add_time(&now, 30, 0);
  oflops_schedule_timer_event(ctx,&now, SND_ACT);

  //action of ping request 
  gettimeofday(&now, NULL);
  add_time(&now, 1, 0);
  oflops_schedule_timer_event(ctx,&now, OFP_PING);

  //get port and cpu status from switch 
  gettimeofday(&now, NULL);
  add_time(&now, 10, 0);
  oflops_schedule_timer_event(ctx,&now, SNMPGET);

  //end process 
  gettimeofday(&now, NULL);
  add_time(&now, 60, 0);
  oflops_schedule_timer_event(ctx,&now, BYESTR);
  return 0;
}
Beispiel #4
0
int 
destroy(struct oflops_context *ctx) {
  char msg[1024];
  struct timeval now;
  FILE *out = fopen(logfile, "w");
  struct entry *np;
  long long t[3], t_sq[3], mean, std;
  int count[3], min_id[3], max_id[3];
  int ch;
  float loss;
  int xid;

  gettimeofday(&now, NULL);
  printf("destroying code\n");
  snprintf(msg, 1024, "OFPT_ERROR_DELAY:%lld", delay_false_modificaton);
  oflops_log(now, GENERIC_MSG, msg);
  snprintf(msg, 1024, "OFPT_INSERT_DELAY:%lld", delay_modificaton);
  oflops_log(now, GENERIC_MSG, msg);

  for(ch = 0; ch < ctx->n_channels-1; ch++) {
    count[ch] = 0;
    min_id[ch] =  INT_MAX;
    max_id[ch] =  INT_MIN;
    t[ch] = 0;
    t_sq[ch] = 0;    
  }

  for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next) {
    if(fprintf(out, "%lu;%lu.%06lu;%lu.%06lu;%d\n", 
	       (long unsigned int)np->id,  
	       (long unsigned int)np->snd.tv_sec, 
	       (long unsigned int)np->snd.tv_usec,
	       (long unsigned int)np->rcv.tv_sec, 
	       (long unsigned int)np->rcv.tv_usec,  np->ch) < 0)  
      perror_and_exit("fprintf fail", 1); 
    ch = np->ch - 1;
    count[ch]++; 
    min_id[ch] = (np->id < min_id[ch])?np->id:min_id[ch];
    max_id[ch] = (np->id > max_id[ch])?np->id:max_id[ch];
    t[ch] += time_diff(&np->snd, &np->rcv);
    t_sq[ch] += time_diff(&np->snd, &np->rcv)*time_diff(&np->snd, &np->rcv);
    free(np);
  }

  for(ch = 0; ch < ctx->n_channels-1; ch++) {
    if(count[ch] == 0) continue;
    mean = t[ch]/count[ch];
    std = (t_sq[ch]/count[ch]) - mean*mean;
    if(std >= 0) std = sqrt(std); else std = LONG_MAX;
    loss = (float)count[ch]/(float)(max_id[ch] - min_id[ch]);
    snprintf(msg, 1024, "statistics:port:%d:%lld:%lld:%.4f:%d", 
	     ctx->channels[ch + 1].of_port, mean, std, loss, count[ch]);
    oflops_log(now, GENERIC_MSG, msg);
  }

  t[0] = 0;
  t_sq[0] = 0;
  for (xid = 1 ; xid < trans_id; xid++) {
    t[0] +=delay[xid];
    t_sq[0] += delay[xid]*delay[xid];
  }
  std = (t_sq[0]/trans_id) - mean*mean;
  std = (std >= 0)?sqrt(std):LONG_MAX;
  snprintf(msg, 1024, "ofp_echo_statistics:%lld:%lld", 
	   t[0]/trans_id, std);
  oflops_log(now, GENERIC_MSG, msg);
  return 0;
}
Beispiel #5
0
int
ofp_msg_log(const void *b, struct pcap_pkthdr hdr) {
  size_t len = hdr.caplen;
  struct ofp_error_msg *err_p = NULL;
  struct ofp_header *ofp = NULL;
  int ret = GENERIC_MSG;
  struct flow fl;

  struct ofp_stats_request *reqp = NULL;
  struct ofp_stats_reply *repp = NULL;
  int count = 0;
  //random inary value to distinguish wether the packet is from the larger
  //port number to the lowest or vice versa. 
  int dir = 0; //client to server

  //since this is a packet capture, strip packet from all the l1-l4 headers.
  int start = parse_ip_packet_header(b, len, &fl);
  if(ntohs(fl.tp_src) < ntohs(fl.tp_dst))
    dir = 1; //server to client 
  if(len - start == 0) {
    //printf("no data in tcp packet\n");
    return -1;
  }
  //printf("initial length: %d, packet length = %d, direction: %d\n", content_length[dir], len - start, dir);

  b += start;
  len -= start;
  while(buff_size[dir] < content_length[dir] + len) {
    buff_size[dir] += INITIAL_BUF_SIZE;
    buff[dir] = realloc(buff[dir], buff_size[dir]);
  }
  //append new packet to the buffer
  memcpy(buff[dir] + content_length[dir], b, len);
  content_length[dir] += len;

  ofp = (struct ofp_header *)buff[dir];

  while((content_length[dir] - count >= sizeof(struct ofp_header)) 
	&& (ntohs(ofp->length) <= (content_length[dir] - count))) {
    //printf("start length: %d, count: %d, length: %d\n", ntohs(ofp->length), count, (content_length[dir] - count));
    assert(ntohs(ofp->length));
//	exit(1);
    switch(ofp->type) {
    case OFPT_HELLO:
      //printf("ofp hello\n");
      oflops_log(hdr.ts, OFPT_HELLO_MSG, "hello message");
      ret = OFPT_HELLO_MSG;
      break;
    case OFPT_STATS_REQUEST:
      reqp = (struct ofp_stats_request *) ofp;
      //printf("stats request\n");
      if (ntohs(reqp->type) == OFPST_FLOW) {
        oflops_log(hdr.ts, OFPT_STATS_REQUEST_FLOW, "stats request send");
        ret = OFPT_STATS_REQUEST_FLOW;
      } 
      break;
    case OFPT_STATS_REPLY:
      repp = (struct ofp_stats_reply *) ofp;
      printf("stats reply\n");
      if (ntohs(repp->type) == OFPST_FLOW) {
        oflops_log(hdr.ts, OFPT_STATS_REPLY_FLOW, "flow stats reply received");
        ret = OFPT_STATS_REPLY_FLOW;
      } else if (ntohs(repp->type) == OFPST_PORT) {
        oflops_log(hdr.ts, OFPT_STATS_REPLY_PORT, "port stats reply received");
        ret = OFPT_STATS_REPLY_PORT;
      }
      break;
    case OFPT_ERROR:
      err_p = (struct ofp_error_msg *)ofp;
      char *msg = xmalloc(sizeof("OFPT_ERROR(type: XXXXXXXXXX, code: XXXXXXXXXX)"));
      sprintf(msg, "OFPT_ERROR(type: %d, code: %d)", ntohs(err_p->type), ntohs(err_p->code));
      oflops_log(hdr.ts, OFPT_ERROR_MSG, msg);
      ret = OFPT_ERROR_MSG;
      break;   
    //default:
    //  printf("msg type: %d, length: %d, code: %d\n", ofp->type, ntohs(ofp->length), count);
    }  
    count += ntohs(ofp->length);
    ofp = (struct ofp_header *)(buff[dir] + count);
    //printf("end length: %d, count: %d, length: %d\n", ntohs(ofp->length), count, (content_length[dir]- count));
  }

  //need to rearrange buffer
  if(count < content_length[dir]) {
    memmove(buff[dir], buff[dir] + count, (content_length[dir] - count));
    content_length[dir] -= count;
  } else
    content_length[dir] = 0;
  return ret;
}