Beispiel #1
0
void parse_ip4(packetinfo *pi)
{
    /* Paranoia */
    if (((pi->packet + pi->eth_hlen) + (IP_HL(pi->ip4) * 4)) > pi->end_ptr) {
        dlog("[D] Refusing to parse IPv4 packet: IPv4-hdr passed end_ptr\n");
        return;
    }
    switch (pi->ip4->ip_p) {
        case IP_PROTO_TCP:
            prepare_tcp(pi);
            parse_tcp(pi);
            break;
        case IP_PROTO_UDP:
            prepare_udp(pi);
            parse_udp(pi);
            break;
        case IP_PROTO_IP4:
            prepare_ip4ip(pi);
            break;
        case IP_PROTO_IP6:
            prepare_ip4ip(pi);
            break;
        default:
            break;
    }
}
Beispiel #2
0
static int parse_layer4(struct packet *packet, u8 *layer4_start,
			int layer4_protocol, int layer4_bytes,
			u8 *packet_end, bool *is_inner, char **error)
{
	if (layer4_protocol == IPPROTO_TCP) {
		*is_inner = true;	/* found inner-most layer 4 */
		return parse_tcp(packet, layer4_start, layer4_bytes, packet_end,
				 error);
	} else if (layer4_protocol == IPPROTO_UDP) {
		*is_inner = true;	/* found inner-most layer 4 */
		return parse_udp(packet, layer4_start, layer4_bytes, packet_end,
				 error);
	} else if (layer4_protocol == IPPROTO_ICMP) {
		*is_inner = true;	/* found inner-most layer 4 */
		return parse_icmpv4(packet, layer4_start, layer4_bytes,
				    packet_end, error);
	} else if (layer4_protocol == IPPROTO_ICMPV6) {
		*is_inner = true;	/* found inner-most layer 4 */
		return parse_icmpv6(packet, layer4_start, layer4_bytes,
				    packet_end, error);
	} else if (layer4_protocol == IPPROTO_GRE) {
		*is_inner = false;
		return parse_gre(packet, layer4_start, layer4_bytes, packet_end,
				 error);
	} else if (layer4_protocol == IPPROTO_IPIP) {
		*is_inner = false;
		return parse_ipv4(packet, layer4_start, packet_end, error);
	} else if (layer4_protocol == IPPROTO_IPV6) {
		*is_inner = false;
		return parse_ipv6(packet, layer4_start, packet_end, error);
	}
	return PACKET_UNKNOWN_L4;
}
Beispiel #3
0
DealStat parse_tran(ParseContext *context, PktStat *pktstat)
{
	TranInfo *traninfo = &(pktstat->info.tran);
	TranInfo *traninfo_as = &(pktstat->info.tran_as);

	AppInfo *appinfo = &(pktstat->info.app);
	AppInfo *appinfo_as = &(pktstat->info.app_as);

	switch (traninfo->type)
	{
		case EU_TRAN_TCP :
			pktstat->owner.portpair = parse_tcp(context, pktstat->owner.hostpair, 
					traninfo->size, traninfo->data, appinfo, appinfo_as);
			goto CONTINUE;
		case EU_TRAN_UDP :
			pktstat->owner.portpair = parse_udp(context, pktstat->owner.hostpair, 
					traninfo->size, traninfo->data, appinfo, appinfo_as);
			goto CONTINUE;
		default :
			goto STOP;
	}

STOP:
	return EU_STOP;
	
CONTINUE:

	return EU_CONTINUE;
}
Beispiel #4
0
static int parse_selector(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

	if (matches(*argv, "u32") == 0) {
		NEXT_ARG();
		res = parse_u32(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (matches(*argv, "u16") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (matches(*argv, "u8") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
		goto done;
	}
	if (matches(*argv, "ip") == 0) {
		NEXT_ARG();
		res = parse_ip(&argc, &argv, sel);
		goto done;
	}
	if (matches(*argv, "ip6") == 0) {
		NEXT_ARG();
		res = parse_ip6(&argc, &argv, sel);
		goto done;
	}
	if (matches(*argv, "udp") == 0) {
		NEXT_ARG();
		res = parse_udp(&argc, &argv, sel);
		goto done;
	}
	if (matches(*argv, "tcp") == 0) {
		NEXT_ARG();
		res = parse_tcp(&argc, &argv, sel);
		goto done;
	}
	if (matches(*argv, "icmp") == 0) {
		NEXT_ARG();
		res = parse_icmp(&argc, &argv, sel);
		goto done;
	}
	return -1;

done:
	*argc_p = argc;
	*argv_p = argv;
	return res;
}
Beispiel #5
0
static int parse_layer4(struct packet *packet, u8 *layer4_start,
			int layer4_protocol, int layer4_bytes,
			u8 *packet_end, char **error)
{
	if (layer4_protocol == IPPROTO_TCP)
		return parse_tcp(packet, layer4_start, layer4_bytes, packet_end,
				 error);
	else if (layer4_protocol == IPPROTO_UDP)
		return parse_udp(packet, layer4_start, layer4_bytes, packet_end,
				 error);
	return PACKET_UNKNOWN_L4;
}
Beispiel #6
0
static int parse_selector(int *argc_p, char ***argv_p,
			  struct tc_u32_sel *sel, struct nlmsghdr *n)
{
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

	if (matches(*argv, "u32") == 0) {
		NEXT_ARG();
		res = parse_u32(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "u16") == 0) {
		NEXT_ARG();
		res = parse_u16(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "u8") == 0) {
		NEXT_ARG();
		res = parse_u8(&argc, &argv, sel, 0, 0);
	} else if (matches(*argv, "ip") == 0) {
		NEXT_ARG();
		res = parse_ip(&argc, &argv, sel);
	} else 	if (matches(*argv, "ip6") == 0) {
		NEXT_ARG();
		res = parse_ip6(&argc, &argv, sel);
	} else if (matches(*argv, "udp") == 0) {
		NEXT_ARG();
		res = parse_udp(&argc, &argv, sel);
	} else if (matches(*argv, "tcp") == 0) {
		NEXT_ARG();
		res = parse_tcp(&argc, &argv, sel);
	} else if (matches(*argv, "icmp") == 0) {
		NEXT_ARG();
		res = parse_icmp(&argc, &argv, sel);
	} else if (matches(*argv, "mark") == 0) {
		NEXT_ARG();
		res = parse_mark(&argc, &argv, n);
	} else if (matches(*argv, "ether") == 0) {
		NEXT_ARG();
		res = parse_ether(&argc, &argv, sel);
	} else
		return -1;

	*argc_p = argc;
	*argv_p = argv;
	return res;
}
Beispiel #7
0
static l4_uint16_t parse_ip(ip_hdr *ip)
{
	char ip1[ipbuf_size];
	char ip2[ipbuf_size];

	print_ip(ip1, &ip->src_addr);
	print_ip(ip2, &ip->dest_addr);

	unsigned char hlen = (ip->ver_hlen & 0x0F) * sizeof(int);

#if 0
	printf("  [IP] version %d, hlen %d, services %d, plen %d, id %d\n",
	       (ip->ver_hlen & 0xF0) >> 4,
	       (ip->ver_hlen & 0x0F),
	       ip->services,
	       ntohs(ip->plen),
	       ntohs(ip->id));
	printf("       flags %x, offset %x, ttl %d, proto %s (%d)\n",
	       (ntohs(ip->flags_frag_offset) & 0x70000000) >> 13,
	       (ntohs(ip->flags_frag_offset) & 0x1FFFFFFF),
	       ip->ttl, ip_proto_str(ip->proto), ip->proto);
	printf("       csum %x, src %s, dest %s\n",
	       ntohs(ip->checksum), ip1, ip2);
#endif

	switch(ip->proto)
	{
		case ip_proto_icmp:
			if (PA_ICMP) parse_icmp((icmp_hdr*)((char*)ip + hlen));
			return ip_proto_icmp;
			break;
		case ip_proto_tcp:
			if (PA_TCP) parse_tcp((tcp_hdr*)((char*)ip + hlen));
			return ip_proto_tcp;
			break;
		case ip_proto_udp:
			if (PA_UDP)  ;
			return parse_udp((udp_hdr*)((char*)ip + hlen));
			break;
		default:
			break;
	}
}
Beispiel #8
0
bool parse_ipv4(int length, uint32_t* data){//parse ipv4 header, false for an unaccepted announcement, true for everything else (including wrong protocol)
	DBG("Length ipv4:%d\n",length);
	struct ip* header = (struct ip*)data;
	if(header->ip_v != 4){//Version
		fprintf(stderr,"No IPv4!\n");
		return true;
	} 

	if(header->ip_hl != 5){//IP Header Length
		fprintf(stderr,"I don't know how to parse a header this size!\n");
		return true;
	}
	//Ignoring a lot of stuff right here
	if(header->ip_p != IPPROTO_UDP){//Checking Protocol for UDP
		fprintf(stderr,"No UDP %d!\n",header->ip_p);
		return true;
	}	
	//Ignoring more stuff, e.g. checksum and source-/destinationaddress
	return parse_udp(length-20,data+5);
}
Beispiel #9
0
void parse_ip6(packetinfo *pi)
{
    switch (pi->ip6->next) {
        case IP_PROTO_TCP:
            prepare_tcp(pi);
            parse_tcp(pi);
            break;
        case IP_PROTO_UDP:
            prepare_udp(pi);
            parse_udp(pi);
            break;
        case IP_PROTO_IP4:
            prepare_ip6ip(pi);
            break;
        case IP_PROTO_IP6:
            prepare_ip6ip(pi);
            break;
        default:
            break;
    }
}
Beispiel #10
0
static void
parse_ip (const struct pcap_pkthdr *header,
          const u_char             *packet)
{
  const struct ip *ip = (struct ip *)packet;
  const u_char *payload = packet + sizeof (struct ip);

  IPAddress address;
  address.sa_family = AF_INET;
  address.src.ip = ip->ip_src;
  address.dst.ip = ip->ip_dst;

  switch (ip->ip_p)
    {
    case (TCP_PROTOCOL_NUMBER):
      parse_tcp (header, payload, &address);
      break;
    case (UDP_PROTOCOL_NUMBER):
      parse_udp (header, payload, &address);
      break;
    default:
      break;
    }
}
Beispiel #11
0
static void
parse_ip6 (const struct pcap_pkthdr *header,
           const u_char             *packet)
{
  const struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
  const u_char *payload = packet + sizeof (struct ip6_hdr);

  IPAddress address;
  address.sa_family = AF_INET6;
  address.src.ip6 = ip6->ip6_src;
  address.dst.ip6 = ip6->ip6_dst;

  switch ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt)
    {
    case (TCP_PROTOCOL_NUMBER):
      parse_tcp (header, payload, &address);
      break;
    case (UDP_PROTOCOL_NUMBER):
      parse_udp (header, payload, &address);
      break;
    default:
      break;
    }
}
/* Initializes 'flow' members from 'packet', 'tun_id', and 'ofp_in_port'.
 * Initializes 'packet' header pointers as follows:
 *
 *    - packet->l2 to the start of the Ethernet header.
 *
 *    - packet->l3 to just past the Ethernet header, or just past the
 *      vlan_header if one is present, to the first byte of the payload of the
 *      Ethernet frame.
 *
 *    - packet->l4 to just past the IPv4 header, if one is present and has a
 *      correct length, and otherwise NULL.
 *
 *    - packet->l7 to just past the TCP or UDP or ICMP header, if one is
 *      present and has a correct length, and otherwise NULL.
 */
void
flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id,
             uint16_t ofp_in_port, struct flow *flow)
{
    struct ofpbuf b = *packet;
    struct eth_header *eth;

    COVERAGE_INC(flow_extract);

    memset(flow, 0, sizeof *flow);
    flow->tun_id = tun_id;
    flow->in_port = ofp_in_port;
    flow->priority = priority;

    packet->l2 = b.data;
    packet->l3 = NULL;
    packet->l4 = NULL;
    packet->l7 = NULL;

    if (b.size < sizeof *eth) {
        return;
    }

    /* Link layer. */
    eth = b.data;
    memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN);
    memcpy(flow->dl_dst, eth->eth_dst, ETH_ADDR_LEN);

    /* dl_type, vlan_tci. */
    ofpbuf_pull(&b, ETH_ADDR_LEN * 2);
    if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
        parse_vlan(&b, flow);
    }
    flow->dl_type = parse_ethertype(&b);

    /* Network layer. */
    packet->l3 = b.data;
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
        const struct ip_header *nh = pull_ip(&b);
        if (nh) {
            packet->l4 = b.data;

            flow->nw_src = get_unaligned_be32(&nh->ip_src);
            flow->nw_dst = get_unaligned_be32(&nh->ip_dst);
            flow->nw_proto = nh->ip_proto;

            flow->nw_tos = nh->ip_tos;
            if (IP_IS_FRAGMENT(nh->ip_frag_off)) {
                flow->nw_frag = FLOW_NW_FRAG_ANY;
                if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) {
                    flow->nw_frag |= FLOW_NW_FRAG_LATER;
                }
            }
            flow->nw_ttl = nh->ip_ttl;

            if (!(nh->ip_frag_off & htons(IP_FRAG_OFF_MASK))) {
                if (flow->nw_proto == IPPROTO_TCP) {
                    parse_tcp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_UDP) {
                    parse_udp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_ICMP) {
                    const struct icmp_header *icmp = pull_icmp(&b);
                    if (icmp) {
                        flow->tp_src = htons(icmp->icmp_type);
                        flow->tp_dst = htons(icmp->icmp_code);
                        packet->l7 = b.data;
                    }
                }
            }
        }
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
        if (parse_ipv6(&b, flow)) {
            return;
        }

        packet->l4 = b.data;
        if (flow->nw_proto == IPPROTO_TCP) {
            parse_tcp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_UDP) {
            parse_udp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_ICMPV6) {
            if (parse_icmpv6(&b, flow)) {
                packet->l7 = b.data;
            }
        }
    } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
        const struct arp_eth_header *arp = pull_arp(&b);
        if (arp && arp->ar_hrd == htons(1)
            && arp->ar_pro == htons(ETH_TYPE_IP)
            && arp->ar_hln == ETH_ADDR_LEN
            && arp->ar_pln == 4) {
            /* We only match on the lower 8 bits of the opcode. */
            if (ntohs(arp->ar_op) <= 0xff) {
                flow->nw_proto = ntohs(arp->ar_op);
            }

            if ((flow->nw_proto == ARP_OP_REQUEST)
                || (flow->nw_proto == ARP_OP_REPLY)) {
                flow->nw_src = arp->ar_spa;
                flow->nw_dst = arp->ar_tpa;
                memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
                memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
            }
        }
    }
}
Beispiel #13
0
int main(int argc, char**argv){

	//log files
	logs = fopen("/var/log/weperf/sensor/sensor.log", "a+");

	int clientSocket;
	char buffer[1024];
	char recv_buff[1024];
	char send_buff[1024];
	struct sockaddr_in serverAddr;
	socklen_t addr_size;

	//parse configurations from file
    if (ini_parse("/etc/weperf/sensor-config.ini", handler, &config) < 0) {
        client_log("Error", "Can't load 'config.ini'\n");
        return 1;
    }

	//casue zombies to be reaped automatically 
	if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
 		perror(0);
  		exit(1);
	}

	/*---- Create the socket. The three arguments are: ----*/
	/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
	clientSocket = socket(PF_INET, SOCK_STREAM, 0);

	/*---- Configure settings of the server address struct ----*/
	/* Address family = Internet */
	serverAddr.sin_family = AF_INET;
	/* Set port number, using htons function to use proper byte order */
	serverAddr.sin_port = htons(config.server_port);
	/* Set IP address to localhost */
	serverAddr.sin_addr.s_addr = inet_addr(config.server_addr);
	/* Set all bits of the padding field to 0 */
	memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

	/*---- Connect the socket to the server using the address struct ----*/
	addr_size = sizeof serverAddr;
	if(connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size)){
		client_log("Error", "Connecting to server - %s", strerror(errno));
		return 0;
	}

	client_log("Info", "Connected to server");

	//get IP of interface - add interface to config file
	struct ifreq ifr;
	strncpy(ifr.ifr_name, config.interface, IFNAMSIZ-1);
	ioctl(clientSocket, SIOCGIFADDR, &ifr);
	struct in_addr local_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;

	printf("Local IP %s\n", inet_ntoa(local_ip));

	//timeout
	struct timeval tv;

	int bytes = 1;
	//receive loop
	while(bytes){

		FILE *fp;

		fd_set rfds;
		FD_ZERO(&rfds);
		FD_SET (clientSocket, &rfds);

		tv.tv_sec = 60;
		tv.tv_usec = 0;
				
		int ready = select(clientSocket + 1, &rfds, NULL, NULL, &tv);

		if(ready == -1 ){

		}else if(ready){
			bytes = recv(clientSocket, recv_buff, sizeof(recv_buff),0);
			struct srrp_request * request = (struct srrp_request *) recv_buff;

			if(request->type == SRRP_HB){
				//heatbeat request
				printf("Received hb request - %d bytes\n", bytes);
				//build response
				response_init((struct srrp_response *) send_buff, request->type, SRRP_SCES, request->dst_id, request->m_id);

				send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff), 0);
			}else if(request->type == SRRP_ETHER){
				//ethernet request
				printf("Received ether request - %d bytes\n", bytes);
				//build response
				response_init((struct srrp_response *) send_buff, request->type, SRRP_SCES, request->dst_id, request->m_id);

				//bit of a hack to break from srrp to send MAC address 
				memcpy(&((struct srrp_response *)send_buff)->results[0], config.ether, strlen(config.ether) + 1);
				//also for the ip
				memcpy(&((struct srrp_response *)send_buff)->results[3], &local_ip, sizeof(local_ip));

				send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff) /*header*/ + 100 /*mac*/ + sizeof(local_ip) /*ip*/, 0);
			}else if(request->type == SRRP_BW){				
				client_log("Info", "Recevived iperf request - %d bytes", bytes);

				if(fork() == 0){
					//listen for SIGCHLD so pclose resturns the status 
					signal(SIGCHLD, SIG_DFL);

					char * cmd_fmt = "iperf -c %s -p %d -t %d -y C";
					char cmd[100];

					//default params
					int dur = 10;

					//get parameters
					int i;
					for(i = 0; i < request->length; i++){
						if(request->params[i].param == SRRP_DUR){
							dur = request->params[i].value;
						}else{
							client_log("Error", "Invalid iperf parameter");
						}
					}

					//build command
					sprintf(cmd, cmd_fmt, inet_ntoa(request->dst_ip), config.tcp_iperf_port, dur);
					printf("%s\n", cmd);

					fp = popen(cmd, "r");
					if(fp == NULL){
						client_log("Error", "Failed to run command '%s'", cmd);
						_exit(1);
					}

					//get otuput	-	single line because of -y C flage
					char result[100];
					while(fgets(result, sizeof(result)-1, fp) != NULL){}

					int exit_status = pclose(fp);
					if(exit_status != 0){
						client_log("Error", "iperf failed exit status %d", exit_status);

						//should send resonpse with failed success code

						_exit(1);
					}else{

						//build response
						if(parse_iperf(request->type, request->dst_id, request->m_id, (struct srrp_response *) send_buff, result)){
							client_log("Error", "Failed to parse iperf response");
							_exit(0);
						}

						client_log("Info", "Sending iperf results");

						send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff), 0);
					}

					_exit(0);
				}

			}else if(request->type == SRRP_RTT){
				client_log("Info", "Received ping request - %d bytes", bytes);

				if(fork() == 0){
					//listen for SIGCHLD so pclose resturns the status 
					signal(SIGCHLD, SIG_DFL);
					
					char * command_fmt = "ping -c %d %s";
					char command[100];

					//default params
					int itterations = 5;

					//load in params
					int i;
					for(i = 0; i < request->length; i++){
						if(request->params[i].param == SRRP_ITTR){
							itterations = request->params[i].value;
						}else{
							client_log("Error", "Invalid ping parameter");
						}
					}

					//build command
					sprintf(command, command_fmt, itterations, inet_ntoa(request->dst_ip));
					printf("%s\n", command);

					fp = popen(command , "r");
					if(fp == NULL){
						client_log("Error", "Failed to run command %s", command);
						_exit(1);
					}

					//get otuput	-	single line because of -y C flage
					char result[100];
					while(fgets(result, sizeof(result)-1, fp) != NULL){}

					int exit_status = pclose(fp);
					if(exit_status != 0){
						client_log("Error", "command failed exit status %d", exit_status);

						//should respond

					}else{

						if(parse_ping(request->type, request->dst_id, request->m_id, (struct srrp_response *) send_buff, result)){
							client_log("Error", "Failed to parse ping response");
							_exit(0);
						}

						send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff), 0);

						_exit(0);
					}

				}	
			}else if(request->type == SRRP_UDP){
				client_log("Info", "Received UDP iperf request - %d bytes", bytes);

				if(fork() == 0){
					//listen for SIGCHLD so pclose resturns the status 
					signal(SIGCHLD, SIG_DFL);

					char * cmd_fmt = "iperf -c %s -u -p %d -b %dK -l %d -t %d -S %d -y C";
					char cmd[100];

					//default params
					int speed = 1;
					int size = 1470;
					int duration = 10;
					int dscp = 0;

					//load in params
					int i;
					for(i = 0; i < request->length; i++){
						if(request->params[i].param == SRRP_SPEED){
							speed = request->params[i].value;
						}else if(request->params[i].param == SRRP_SIZE){
							size = request->params[i].value;
						}else if(request->params[i].param == SRRP_DUR){
							duration = request->params[i].value;
						}else if(request->params[i].param == SRRP_DSCP){
							dscp = request->params[i].value;
						}else{
							client_log("Error", "Invalid udp parameter");
						}
					}

					sprintf(cmd, cmd_fmt, inet_ntoa(request->dst_ip), config.udp_iperf_port, speed, size, duration, dscp);

					printf("%s\n", cmd);

					fp = popen(cmd , "r");
					if(fp == NULL){
						client_log("Error", "Failed to run command %s", cmd);
						_exit(1);
					}

					//get otuput	-	single line because of -y C flage
					char result[200];
					while(fgets(result, sizeof(result)-1, fp) != NULL)
						printf("%s\n", result);

					int exit_status = pclose(fp);
					if(exit_status != 0){
						client_log("Error", "udp iperf failed exit status %d", exit_status);

						//should send resonpse with failed success code
						//parse_failure()

						_exit(1);
					}else{

						if(parse_udp(request->type, request->dst_id, request->m_id, (struct srrp_response *) send_buff, result, speed, dscp)){
							client_log("Error", "Failed to parse udp response");
							_exit(0);
						}

						send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff), 0);

						client_log("Info", "Sending udp iperf results");

						_exit(0);
					}
				}

			}else if(request->type == SRRP_DNS){
				client_log("Info", "Received dns request - %d bytes", bytes);

				if(fork() == 0){
					//listen for SIGCHLD so pclose resturns the status 
					signal(SIGCHLD, SIG_DFL);

					char * cmd_fmt = "nslookup %s %s";
					char cmd[100];

					char * domain_name 	= NULL;
					char * server 		= NULL;

					int i = 0;
					while(i < request->length){
						if(request->params[i].param == SRRP_DN){
							i = get_param_string(&domain_name, request, i);	
						}else if(request->params[i].param == SRRP_SERVER){
							i = get_param_string(&server, request, i);
						}else{
							client_log("Error", "Invalid param");
						}
					}

					if(!server || strcmp(server, "default") == 0)
						server = "";
					if(!domain_name || strcmp(server, "default") == 0)
						domain_name = (char *)config.nslookup_addr;

					sprintf(cmd, cmd_fmt, domain_name, server);

					printf("%s\n", cmd);

					struct timeval start, end;
					float mtime, secs, usecs;

					gettimeofday(&start, NULL);

					fp = popen(cmd , "r");
					if(fp == NULL){
						client_log("Error", "Failed to run command %s", cmd);
						_exit(1);
					}

					//get otuput
					char result[200];
					while(fgets(result, sizeof(result)-1, fp) != NULL){}

					//work out resolution time
					gettimeofday(&end, NULL);
					secs  = end.tv_sec  - start.tv_sec;
					usecs = end.tv_usec - start.tv_usec;
					mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;

					int exit_status = pclose(fp);
					if(exit_status != 0){
						client_log("Info", "DNS status failure - exit status %d", exit_status);
						parse_failure(request->type, request->dst_id, request->m_id, (struct srrp_response *) send_buff);
					}else{
						client_log("Info", "DNS status sucess - exit status %d", exit_status);	
						parse_dns(request->type, request->dst_id, request->m_id, (struct srrp_response *) send_buff, mtime);
					}					

					send(clientSocket, send_buff, response_size((struct srrp_response *) send_buff), 0);

					client_log("Info", "Sending dns response");				

					_exit(0);
				}

			}else{
				//unrecognised data
				client_log("Error", "Recevied unrecognised data - %d - %d bytes", request->type, bytes);
			}
		}else{
			//timeout
			//dont care about timeout --- keep running
			client_log("Error", "Timeout");
			break;
		}
	}

	client_log("Info", "Recevied empty data, closing connection");

	fclose(logs);
	close(clientSocket);  

	return 0;
}
Beispiel #14
0
void parse_ip(char * packet, int packet_size){
    
    int BUF_SIZE = 9;
    int pointer = 0;
    unsigned long int IHL = 0;
    unsigned long int proto = 0;
    unsigned long int length = 0;

    if(strncmp(packet, "4", 1) == 0){
       printf("IPv4\n");
    }
    else if(strncmp(packet, "6", 1) == 0){
        printf("IPv6\nNOT SUPPORTED\n");
        return;
    }
    else{
        printf("Unknown IP type\n");
        return;
    }
    pointer += 1;
    

    char * buf = (char *) malloc(BUF_SIZE);
    memset(buf, 0, BUF_SIZE);

    //IHL
    strncpy(buf, packet + pointer, 1);
    printf("IHL: %s (%d * 4 = %dbytes)\n", buf, strtoul(buf, NULL, 16), strtoul(buf, NULL, 16) * 4); 
    IHL = strtoul(buf, NULL, 16);
    pointer += 1;

    //DSCP and ECN
    strncpy(buf, packet + pointer, 2);
    printf("DSCP & ECN: %s\n", buf);
    pointer += 2;

    //Total lenght
    strncpy(buf, packet + pointer, 4);
    length = strtoul(buf, NULL, 16);
    printf("Total length: %s (%dbytes)\n", buf, length);
    pointer += 4;
    
    //Identification
    strncpy(buf, packet + pointer, 4);
    printf("Identification: %s (%d)\n", buf, strtoul(buf, NULL, 16));
    pointer += 4;

    //Flags and Frag offset
    strncpy(buf, packet + pointer, 4);
    printf("Flags and Frag: %s\n", buf);
    pointer += 4;

    memset(buf, 0, BUF_SIZE); //Ugly hack as sizes get smaller again

    //TTL
    strncpy(buf, packet + pointer, 2);
    printf("TTL: %s (%d)\n", buf, strtoul(buf, NULL, 16));
    pointer += 2;

    //Proto
    strncpy(buf, packet + pointer, 2);
    proto = strtoul(buf, NULL, 16);
    printf("Proto: %s (%d)\n", buf, proto);
    pointer += 2;

    //Checksum
    strncpy(buf, packet + pointer, 4);
    printf("Checksum: %s (%d)\n", buf, strtoul(buf, NULL, 16));
    pointer += 4;

    //Source
    strncpy(buf, packet + pointer, 8);
    printf("Source: %s (%s)\n", buf, hex_to_ip(buf));
    pointer += 8;

    //Dest
    strncpy(buf, packet + pointer, 8);
    printf("Dest: %s (%s)\n", buf, hex_to_ip(buf));
    pointer += 8;

    if(IHL > 5){
        printf("OPTIONS NOT IMPLEMENTED\n");
        pointer = IHL * 8;
    }

    printf("\n");

    free(buf);
    
    if(TOTAL_SIZE == 0){
        TOTAL_SIZE = length;
    }

    SIZE_PTR += pointer / 2;

    printf("SIZE_PTR: %d\n", SIZE_PTR);

    if(proto == ICMP){
        parse_icmp(packet + pointer, packet_size - pointer); 
    }
    else if(proto == TCP){
        SIZE_PTR += parse_tcp(packet + pointer, packet_size - pointer);
    }
    else if(proto == UDP){
        SIZE_PTR += parse_udp(packet + pointer, packet_size - pointer);
    }
}
Beispiel #15
0
/* Initializes l3 and higher 'flow' members from 'packet'
 *
 * This should be called by or after flow_extract()
 *
 * Initializes 'packet' header pointers as follows:
 *
 *    - packet->l4 to just past the IPv4 header, if one is present and has a
 *      correct length, and otherwise NULL.
 *
 *    - packet->l7 to just past the TCP or UDP or ICMP header, if one is
 *      present and has a correct length, and otherwise NULL.
 */
void
flow_extract_l3_onwards(struct ofpbuf *packet, struct flow *flow,
                        ovs_be16 dl_type)
{
    struct ofpbuf b;

    ofpbuf_use_const(&b, packet->l3, packet->size -
                     (size_t)((char *)packet->l3 - (char *)packet->l2));

    /* Network layer. */
    if (dl_type == htons(ETH_TYPE_IP)) {
        const struct ip_header *nh = pull_ip(&b);
        if (nh) {
            packet->l4 = b.data;

            flow->nw_src = get_unaligned_be32(&nh->ip_src);
            flow->nw_dst = get_unaligned_be32(&nh->ip_dst);
            flow->nw_proto = nh->ip_proto;

            flow->nw_tos = nh->ip_tos;
            if (IP_IS_FRAGMENT(nh->ip_frag_off)) {
                flow->nw_frag = FLOW_NW_FRAG_ANY;
                if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) {
                    flow->nw_frag |= FLOW_NW_FRAG_LATER;
                }
            }
            flow->nw_ttl = nh->ip_ttl;

            if (!(nh->ip_frag_off & htons(IP_FRAG_OFF_MASK))) {
                if (flow->nw_proto == IPPROTO_TCP) {
                    parse_tcp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_UDP) {
                    parse_udp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_ICMP) {
                    const struct icmp_header *icmp = pull_icmp(&b);
                    if (icmp) {
                        flow->tp_src = htons(icmp->icmp_type);
                        flow->tp_dst = htons(icmp->icmp_code);
                        packet->l7 = b.data;
                    }
                }
            }
        }
    } else if (dl_type == htons(ETH_TYPE_IPV6)) {
        if (parse_ipv6(&b, flow)) {
            return;
        }

        packet->l4 = b.data;
        if (flow->nw_proto == IPPROTO_TCP) {
            parse_tcp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_UDP) {
            parse_udp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_ICMPV6) {
            if (parse_icmpv6(&b, flow)) {
                packet->l7 = b.data;
            }
        }
    } else if (dl_type == htons(ETH_TYPE_ARP) ||
               dl_type == htons(ETH_TYPE_RARP)) {
        const struct arp_eth_header *arp = pull_arp(&b);
        if (arp && arp->ar_hrd == htons(1)
            && arp->ar_pro == htons(ETH_TYPE_IP)
            && arp->ar_hln == ETH_ADDR_LEN
            && arp->ar_pln == 4) {
            /* We only match on the lower 8 bits of the opcode. */
            if (ntohs(arp->ar_op) <= 0xff) {
                flow->nw_proto = ntohs(arp->ar_op);
            }

            flow->nw_src = arp->ar_spa;
            flow->nw_dst = arp->ar_tpa;
            memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
            memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
        }
    }
}
void *plmc_udp_listener(void *arguments) 
{
	int sockfd, msg_length;
	struct sockaddr_in servaddr, cliaddr;
	struct in_addr inp;
	socklen_t addr_length;
	char mesg[PLMC_MAX_UDP_DATA_LEN];
	udp_msg udpmsg;
	char *match_ip;
	
	#ifdef PLMC_LIB_DEBUG
	fprintf(plmc_lib_debug, "plmc_udp_listener started\n");
	fflush(plmc_lib_debug);
	#endif 
	/* Get the socket */
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		syslog(LOG_ERR, "plmc_lib: encountered an error opening a "
								"socket");
		send_error(PLMC_LIBERR_SYSTEM_RESOURCES, 
			PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD);
		if (pthread_cancel(tcp_listener_id) != 0) {
			send_error(PLMC_LIBERR_SYSTEM_RESOURCES, 
				PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD);
			syslog(LOG_ERR, "plmc_lib: encountered an error "
						"canceling tcp_listener");
		}
		pthread_exit((void *)NULL);
	}

	/*
	* Here we need to register a cleanup function that will be called in 
	* case the UDP listener gets canceled by the library. This is to close 
	* the socket.
	*/
	pthread_cleanup_push(udp_listener_cleaner, (void *)&sockfd);

	match_ip = plmc_get_listening_ip_addr(plmc_config_file);
	if (strlen(match_ip) == 0) {
		syslog(LOG_ERR, "plmc_udp_listener cannot match available "
				"network insterfaces with IPs of controllers "
				"specified in the plmcd.conf file");
		send_error(PLMC_LIBERR_NO_CONF, PLMC_LIBACT_DESTROY_LIBRARY, 
							NULL, PLMC_NOOP_CMD);
		pthread_exit((void *)NULL);
	}
	inet_aton(match_ip, &inp);

	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inp.s_addr;
	servaddr.sin_port=htons(atoi(config.udp_broadcast_port));
	if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
		syslog(LOG_ERR, "plmc_lib: encountered an error during a "
							"call to bind()");
		syslog(LOG_ERR, "plmc_lib: errnor is %d", errno);
		send_error(PLMC_LIBERR_SYSTEM_RESOURCES, 
						PLMC_LIBACT_DESTROY_LIBRARY,
						NULL, PLMC_NOOP_CMD);
		if (pthread_cancel(tcp_listener_id) != 0) {
			send_error(PLMC_LIBERR_SYSTEM_RESOURCES, 
				PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD);
			syslog(LOG_ERR, "plmc_lib: encountered an error "
						"canceling tcp_listener");
		}
		pthread_exit((void *)NULL);
	}

	/*
	We are now entering the while loop. We will hang out here till somebody
	cancels us
	*/
	while (1) {
		addr_length = sizeof(cliaddr);
		msg_length = recvfrom(sockfd,mesg,PLMC_MAX_UDP_DATA_LEN,
				0,(struct sockaddr *)&cliaddr,&addr_length);
		mesg[msg_length] = '\0';
		#ifdef PLMC_LIB_DEBUG
		fprintf(plmc_lib_debug, "plmc_udp_listener got a new message: "
								"%s\n", mesg);
		fflush(plmc_lib_debug);
		#endif 

		/* Get the struct setup */
		if (parse_udp(&udpmsg, mesg) != 0) {
			syslog(LOG_ERR, "plmc_lib: UDP message invalid %s", 
									mesg);
			send_error(PLMC_LIBERR_MSG_INVALID, 
				PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD);
			continue;
		}
		if ((callbacks.udp_cb(&udpmsg)) != 0) {
			syslog(LOG_ERR, "plmc_lib: encountered an error "
				"during the UDP callback call to PLMSv");
			send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING,
					udpmsg.ee_id, PLMC_NOOP_CMD);
			continue;
		}
	}
	/* 
	Remove the cleanup for the connected socket
	Normally the code will never get here.
	*/
	pthread_cleanup_pop(0);
}
Beispiel #17
0
/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
 * 'in_port'.
 *
 * Initializes 'packet' header pointers as follows:
 *
 *    - packet->l2 to the start of the Ethernet header.
 *
 *    - packet->l2_5 to the start of the MPLS shim header.
 *
 *    - packet->l3 to just past the Ethernet header, or just past the
 *      vlan_header if one is present, to the first byte of the payload of the
 *      Ethernet frame.
 *
 *    - packet->l4 to just past the IPv4 header, if one is present and has a
 *      correct length, and otherwise NULL.
 *
 *    - packet->l7 to just past the TCP/UDP/SCTP/ICMP header, if one is
 *      present and has a correct length, and otherwise NULL.
 */
void
flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
             const struct flow_tnl *tnl, const union flow_in_port *in_port,
             struct flow *flow)
{
    struct ofpbuf b = *packet;
    struct eth_header *eth;

    COVERAGE_INC(flow_extract);

    memset(flow, 0, sizeof *flow);

    if (tnl) {
        ovs_assert(tnl != &flow->tunnel);
        flow->tunnel = *tnl;
    }
    if (in_port) {
        flow->in_port = *in_port;
    }
    flow->skb_priority = skb_priority;
    flow->pkt_mark = pkt_mark;

    packet->l2   = b.data;
    packet->l2_5 = NULL;
    packet->l3   = NULL;
    packet->l4   = NULL;
    packet->l7   = NULL;

    if (b.size < sizeof *eth) {
        return;
    }

    /* Link layer. */
    eth = b.data;
    memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN);
    memcpy(flow->dl_dst, eth->eth_dst, ETH_ADDR_LEN);

    /* dl_type, vlan_tci. */
    ofpbuf_pull(&b, ETH_ADDR_LEN * 2);
    if (eth->eth_type == htons(ETH_TYPE_VLAN)) {
        parse_vlan(&b, flow);
    }
    flow->dl_type = parse_ethertype(&b);

    /* Parse mpls, copy l3 ttl. */
    if (eth_type_mpls(flow->dl_type)) {
        packet->l2_5 = b.data;
        parse_mpls(&b, flow);
    }

    /* Network layer. */
    packet->l3 = b.data;
    if (flow->dl_type == htons(ETH_TYPE_IP)) {
        const struct ip_header *nh = pull_ip(&b);
        if (nh) {
            packet->l4 = b.data;

            flow->nw_src = get_16aligned_be32(&nh->ip_src);
            flow->nw_dst = get_16aligned_be32(&nh->ip_dst);
            flow->nw_proto = nh->ip_proto;

            flow->nw_tos = nh->ip_tos;
            if (IP_IS_FRAGMENT(nh->ip_frag_off)) {
                flow->nw_frag = FLOW_NW_FRAG_ANY;
                if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) {
                    flow->nw_frag |= FLOW_NW_FRAG_LATER;
                }
            }
            flow->nw_ttl = nh->ip_ttl;

            if (!(nh->ip_frag_off & htons(IP_FRAG_OFF_MASK))) {
                if (flow->nw_proto == IPPROTO_TCP) {
                    parse_tcp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_UDP) {
                    parse_udp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_SCTP) {
                    parse_sctp(packet, &b, flow);
                } else if (flow->nw_proto == IPPROTO_ICMP) {
                    const struct icmp_header *icmp = pull_icmp(&b);
                    if (icmp) {
                        flow->tp_src = htons(icmp->icmp_type);
                        flow->tp_dst = htons(icmp->icmp_code);
                        packet->l7 = b.data;
                    }
                }
            }
        }
    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
        if (parse_ipv6(&b, flow)) {
            return;
        }

        packet->l4 = b.data;
        if (flow->nw_proto == IPPROTO_TCP) {
            parse_tcp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_UDP) {
            parse_udp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_SCTP) {
            parse_sctp(packet, &b, flow);
        } else if (flow->nw_proto == IPPROTO_ICMPV6) {
            if (parse_icmpv6(&b, flow)) {
                packet->l7 = b.data;
            }
        }
    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
               flow->dl_type == htons(ETH_TYPE_RARP)) {
        const struct arp_eth_header *arp = pull_arp(&b);
        if (arp && arp->ar_hrd == htons(1)
            && arp->ar_pro == htons(ETH_TYPE_IP)
            && arp->ar_hln == ETH_ADDR_LEN
            && arp->ar_pln == 4) {
            /* We only match on the lower 8 bits of the opcode. */
            if (ntohs(arp->ar_op) <= 0xff) {
                flow->nw_proto = ntohs(arp->ar_op);
            }

            flow->nw_src = get_16aligned_be32(&arp->ar_spa);
            flow->nw_dst = get_16aligned_be32(&arp->ar_tpa);
            memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
            memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
        }
    }
}