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; } }
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_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; } }
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; } }
void *plmc_client_mgr(void *arguments) { thread_entry *tentry; thread_data *tdata; char command[PLMC_CMD_NAME_MAX_LENGTH]; char result[PLMC_MAX_TCP_DATA_LEN]; char ee_id[PLMC_EE_ID_MAX_LENGTH]; PLMC_cmd_idx cmd_enum; int sockfd, retval, bytes_received; struct timeval tv; int( *callback)(tcp_msg *); tentry = (thread_entry *) arguments; tdata = &(tentry->thread_d); command[0] ='\0'; /* Adding 10 seconds to the plmc_cmd_timeout_secs in the * plmcd.conf file */ tv.tv_sec = config.plmc_cmd_timeout_secs + 10; tv.tv_usec = 0; tcp_msg tcpmsg; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr started up\n"); fflush(plmc_lib_debug); #endif /* Lock to get the socket */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered an " "error getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, NULL, PLMC_NOOP_CMD); pthread_exit((void *)NULL); } sockfd = tentry->thread_d.socketfd; strncpy(ee_id, tdata->ee_id, PLMC_EE_ID_MAX_LENGTH); ee_id[PLMC_EE_ID_MAX_LENGTH - 1] = '\0'; /* * There is a new command, copy it locally and return the * lock */ strncpy(command, tdata->command, PLMC_CMD_NAME_MAX_LENGTH); command[PLMC_CMD_NAME_MAX_LENGTH - 1] = '\0'; cmd_enum = plmc_cmd_string_to_enum(tdata->command); /* Get the callback as well */ callback = tdata->callback; /* Unlock */ if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr got a new command %s for " "ee_id %s\n", command, ee_id); fflush(plmc_lib_debug); #endif /* * Change the socket option so that it waits for tv.tv_sec seconds * for a respons */ if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to setsockopt() from client_mgr"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); syslog(LOG_ERR, "plmc_lib: Closing socket and exiting " "client_mgr"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, ee_id, cmd_enum); if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to close_socket"); } pthread_exit((void *)NULL); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Sending command to client\n"); fflush(plmc_lib_debug); #endif /* Send the command to PLMc */ retval = send(sockfd, command, strlen(command), 0); if (retval <= 0) { syslog(LOG_ERR, "plmc_lib: Client Mgr encountered an error " "during a call to send(). Leaving cleanup for " "connection mgr"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); /* Connection MGR will send error to plmc_lib */ pthread_exit((void *)NULL); } /* Get the response */ bytes_received = recv(sockfd, result, PLMC_MAX_TCP_DATA_LEN, 0); if (bytes_received <= 0 ){ /* * The client didn't come back in time. Can't * hang around waiting for this guy. Close this * socket. He'll just have to reconnect */ syslog(LOG_ERR, "plmc_lib: Client Mgr encountered an " "error during a call to recv(). Leaving " "cleanup for connection mgr"); /* Send a timeout error */ send_error(PLMC_LIBERR_TIMEOUT, PLMC_LIBACT_CLOSE_SOCKET, ee_id, cmd_enum); /* Lock to change the socket */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: client_mgr encountered an " "error getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, ee_id, cmd_enum); pthread_exit((void *)NULL); } if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to close_socket"); } /* * Set socketfd to zero to indicate to connection_mgr * that we are gone */ tentry->thread_d.socketfd = 0; tdata->td_id = 0; tdata->kill = 1; if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered " "an error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } pthread_exit((void *)NULL); } result[bytes_received] = '\0'; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Got command back %s\n", result); fflush(plmc_lib_debug); #endif if (parse_tcp(&tcpmsg, result) != 0) { syslog(LOG_ERR, "plmc_lib: TCP message " "invalid %s", result); send_error(PLMC_LIBERR_MSG_INVALID, PLMC_LIBACT_IGNORING, ee_id, cmd_enum); pthread_exit((void *)NULL); } /* Get lock */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: client_mgr encountered an error " "getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to close_socket"); } pthread_exit((void *)NULL); } /* Tell the world we are done with this guy */ tdata->done = 1; tdata->td_id = 0; /* We are exiting */ /* Unlock */ if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered an " "error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } /* Send callback */ if ((callback(&tcpmsg)) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during the " "result callback call to PLMSv"); send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING, ee_id, cmd_enum); pthread_exit((void *)NULL); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Done with command, " "exiting\n"); fflush(plmc_lib_debug); #endif pthread_exit((void *)NULL); }
void *plmc_tcp_listener(void *arguments) { int sockfd, connected, true=1, bytes_received; unsigned int sin_size; struct sockaddr_in servaddr, cliaddr; struct timeval tv; struct in_addr inp; char recv_mesg[PLMC_MAX_TCP_DATA_LEN], *match_ip; pthread_attr_t udp_attr; thread_entry *tentry; int retval = 0; tcp_msg tcpmsg; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener started\n"); fflush(plmc_lib_debug); #endif /* Set the timeout value for recieve messages from clients */ tv.tv_sec = 2; tv.tv_usec = 0; /* Get the socket */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 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); pthread_exit((void *)NULL); } /* Here we need to register a cleanup function that will be called in case the listener gets canceled by the library. This is to close the socket and to cancel all children */ pthread_cleanup_push(tcp_listener_cleaner, (void *)&sockfd); /* Set some socket options, not sure we need this */ if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during a " "call to setsockopt()"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); } /* Set up the IP stuff */ match_ip = plmc_get_listening_ip_addr(plmc_config_file); if (strlen(match_ip) == 0) { syslog(LOG_ERR, "plmc_tcp_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); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(config.tcp_plms_listening_port)); servaddr.sin_addr.s_addr = inp.s_addr; bzero(&(servaddr.sin_zero),8); /* Socket Address to server */ if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -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); close(sockfd); pthread_exit((void *)NULL); } /* Spec max # queued up plmc connections */ if (listen(sockfd, 5) == -1) { syslog(LOG_ERR, "plmc_lib: encountered an error during a call " "to listen()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); close(sockfd); pthread_exit((void *)NULL); } sin_size = sizeof(struct sockaddr_in); /* Set threads detached as we don't want to join them */ pthread_attr_init(&udp_attr); pthread_attr_setdetachstate(&udp_attr, PTHREAD_CREATE_DETACHED); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener starting the UDP thread\n"); fflush(plmc_lib_debug); #endif /* Create the UDP thread */ if (pthread_create(&(udp_listener_id), &udp_attr, plmc_udp_listener, NULL) != 0) { syslog(LOG_ERR, "plmc_lib: Could not create the UDP thread"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); close(sockfd); pthread_exit((void *)NULL); } /* * This is the while loop that will take in new connections and * start client_mgr threads that deal with those connections. */ while (1) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener entering the while " "loop\n"); fflush(plmc_lib_debug); #endif connected = accept(sockfd, (struct sockaddr *)&cliaddr, &sin_size); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener got a new " "connection\n"); fflush(plmc_lib_debug); #endif if (connected < 0) { syslog(LOG_ERR, "plmc_lib: encoutered a problem in " "the accept() call"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); continue; } /* * Push another cleanup function as we have opened a new * socket (connected) and have not yet handed it over to a child * thread (client_mgr). If we get canceled here we need to close * that socket. */ pthread_cleanup_push(client_mgr_cleaner, (void *)&connected); /* Set the timeout SO_RCVTIMEO for the new socket This so a client can't hang the listener for too long */ if (setsockopt (connected, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to setsockopt()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_NOOP_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); } continue; } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener sending a request " "for the ee_id\n"); fflush(plmc_lib_debug); #endif /* Send a request for the ee_id to the client */ retval = send(connected, PLMC_cmd_name[PLMC_GET_ID_CMD], strlen(PLMC_cmd_name[PLMC_GET_ID_CMD]), 0); if (retval < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to send()"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); } continue; } /* Now wait for the response for tv time */ bytes_received = recv(connected, recv_mesg, PLMC_MAX_TCP_DATA_LEN, 0); if (bytes_received < 0 ){ /* The client didn't come back in time. Can't hang around waiting for this guy. Close this socket. He'll just have to reconnect */ syslog(LOG_ERR, "plmc_lib: The client is taking too " "long to respond, closing socket"); send_error(PLMC_LIBERR_TIMEOUT, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); } continue; } recv_mesg[bytes_received] = '\0'; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener got response back: " "%s\n", recv_mesg); fflush(plmc_lib_debug); #endif if (parse_tcp(&tcpmsg, recv_mesg) != 0) { syslog(LOG_ERR, "plmc_lib: Invalid TCP message " "during GET_EE_ID"); send_error(PLMC_LIBERR_MSG_INVALID, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); } continue; } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener creating thread " "entry with ee_id %s and socket %d\n", tcpmsg.ee_id, connected); fflush(plmc_lib_debug); #endif /* Create the thread_entry - This is thread safe */ tentry = create_thread_entry(tcpmsg.ee_id, connected); if (tentry == NULL) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener found an " "entry that has to be closed, " "closing socket on current client\n"); fflush(plmc_lib_debug); #endif close_socket(connected); } else { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener didn't " "find an entry that has to be closed. " "We can reuse this entry\n"); fflush(plmc_lib_debug); #endif if ((callbacks.connect_cb(tcpmsg.ee_id, PLMC_CONN_CB_MSG)) != 0) { send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING, tcpmsg.ee_id, PLMC_GET_ID_CMD); } } /* * Remove the cleanup for the connected socket as we don't care * about that anymore. This socket is now handled by the * client_mgr and this guy will close it if it is canceled */ pthread_cleanup_pop(0); } pthread_cleanup_pop(1); pthread_exit((void *)NULL); }
/* 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); } } }
/* 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 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 '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); } } } }