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; } }
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; }
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; }
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; }
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; }
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; }
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; } }
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); }
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; } }
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; } }
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); } } } }
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; }
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); } }
/* 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); }
/* 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); } } }