diff options
Diffstat (limited to 'src/packet_io/flwd_packet_io_socket.c')
| -rw-r--r-- | src/packet_io/flwd_packet_io_socket.c | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/src/packet_io/flwd_packet_io_socket.c b/src/packet_io/flwd_packet_io_socket.c new file mode 100644 index 0000000..6dad448 --- /dev/null +++ b/src/packet_io/flwd_packet_io_socket.c @@ -0,0 +1,376 @@ +#include "flowood.h" +#include "flowood_fun.h" +#include "flwd_net.h" +#include <pcap/pcap.h> +#include "MESA_list_queue.h" +#include "MESA_handle_logger.h" +#include "MESA_prof_load.h" +#include <sys/types.h> +#include <sys/socket.h> +#include <string.h> +#include <arpa/inet.h> +#include <assert.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <net/if_arp.h> +#include <net/if.h> +#include <stdlib.h> + +#ifdef __cplusplus +/* ��Ҫ��̬dlopen��ȡ������, ʹ��C�淶 */ +extern "C" { +#endif + + +typedef struct { + pthread_t pid; + unsigned char thread_seq; + int sd; /* socket���, UDP��, DGRAMģʽ */ + struct sockaddr sock_addr; +}socket_work_thread_t; + +typedef struct{ + char *__data_buf; /* mbuff������ͷָ�� */ + char *data_actual_ptr; /* ��ǰ����ʵ�ʴ洢������ָ��, ��MAC��ʼ��û��Ҳ��Ԥ���ռ�α��һ��, ����socketģʽ */ + int __data_buf_max_len; /* mbuff��泤��, ��FLWD_LINK_MTU */ + int data_actual_len; /* ��ǰ������ʵ�ʴ洢�����ݳ��� */ +}socket_mbuff_t; + +/* pcapģʽ�ڲ�����ṹ */ +typedef struct{ + int tot_thread_count; + int *socket_dev_handle; /* sd�����ָ�� */ + socket_work_thread_t socket_io_thread_para[FLWD_MAX_THREAD_NUM]; + socket_mbuff_t socket_send_buf[FLWD_MAX_THREAD_NUM]; /* ��������, ��ʼ��ʱ����, �Ժ�����ÿ�ζ�̬malloc/free */ +}flwd_device_handle_socket_t; + + + +/* �˺���������������ѭ��, һֱ������ */ +void low_level_io_run(flwd_device_handle_t *global_io_handle) +{ + /* socketģʽ, init�ɹ���, ������������ӿ�, ֱ��recv, send���� */ + (void )global_io_handle; + + return; +} + + +static socket_mbuff_t *flwd_socket_create_new_mbuff(int datalen) +{ + socket_mbuff_t *sock_mbuff; + + sock_mbuff = (socket_mbuff_t *)calloc(1, sizeof(socket_mbuff_t)); + + sock_mbuff->__data_buf = (char *)malloc(datalen + FLWD_VXLAN_OUTER_PACKET_LEN); /* Ԥ��vxlanͷ�� */ + sock_mbuff->__data_buf_max_len = datalen + FLWD_VXLAN_OUTER_PACKET_LEN; + + + sock_mbuff->data_actual_ptr = sock_mbuff->__data_buf + FLWD_VXLAN_OUTER_PACKET_LEN; + sock_mbuff->data_actual_len = datalen; + + return sock_mbuff; +} + +/* socket addr_para: addr_para=127.0.0.1:50000 */ +int flwd_socket_addr_para_parse(char *cfg_line, unsigned int *sock_addr_ip_net_order, unsigned short *sock_addr_port_host_order) +{ + const char *delim = ": "; + char *save_ptr; + char *section; + int tmp; + + section = strtok_r(cfg_line, delim, &save_ptr); + if(inet_pton(AF_INET, cfg_line, sock_addr_ip_net_order) <= 0){ + return -1; + } + + section = strtok_r(NULL, delim, &save_ptr); + if(NULL == section){ + return -1; + } + + tmp = atoi(section); + if(tmp <= 0 || tmp > 65535){ + return -1; + } + + *sock_addr_port_host_order = (unsigned short)tmp; + + while(strtok_r(NULL, delim, &save_ptr)); + + return 0; +} + +/* Ϊ��gdb��ϵ㷽��, ÿ��io_lib���Լ��ڲ����صĺ������� */ +static int socket_low_level_io_init(flwd_device_handle_t *global_dev_handle) +{ + int i, tmp_int; + char str_tmp[128]; + unsigned int sock_addr_ip_net_order = 0; /* socketģʽ������IP */ + unsigned short sock_addr_port_host_order; /* ��ʼ�˿�, һ���ӵ�ǰ�˿ڿ�ʼ��port + thread_count */ + struct sockaddr_in sockadd; + + flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)calloc(1, sizeof(flwd_device_handle_socket_t)); + + /* socket addr_para: addr_para=60000, ��ʾ���ذ���ʼ�˿�, �Լ�������thread_num�������˿� */ + MESA_load_profile_string_def(FLWD_CONFIG_FILE, g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section, "addr_para", str_tmp, 128, "#"); + if('#' == str_tmp[0]){ + flwd_log(RLOG_LV_FATAL, "get config %s->addr_para error!", g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section); + return -1; + } + +#if 0 + ret = flwd_socket_addr_para_parse(str_tmp, &sock_addr_ip_net_order, &sock_addr_port_host_order); + if(ret < 0){ + flwd_log(RLOG_LV_FATAL, "parse config %s->addr_para %s error!", + g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section, str_tmp); + return -1; + } +#else + tmp_int = atoi(str_tmp); + if((tmp_int <= 0) || (tmp_int > 65535)){ + flwd_log(RLOG_LV_FATAL, "%s config %s->addr_para error!", g_packet_io_cfg_para[(int)global_dev_handle->io_para.topo_mode].cfg_file_section); + return -1; + } +#endif + + sock_addr_port_host_order = (unsigned short)tmp_int; + + for(i = 0; i < global_dev_handle->tot_thread_count; i++){ + socket_io_handle->socket_io_thread_para[i].thread_seq = i; + socket_io_handle->socket_send_buf[i].__data_buf = (char *)malloc(FLWD_LINK_MTU); + socket_io_handle->socket_send_buf[i].__data_buf_max_len = FLWD_LINK_MTU; + socket_io_handle->socket_io_thread_para[i].sd = socket(AF_INET, SOCK_DGRAM, 0); + + bzero(&sockadd, sizeof(sockadd)); + sockadd.sin_family = AF_INET; + sockadd.sin_addr.s_addr = sock_addr_ip_net_order; + sockadd.sin_port = htons(sock_addr_port_host_order + i); + + if(bind(socket_io_handle->socket_io_thread_para[i].sd, (struct sockaddr *) &sockadd, sizeof(sockadd)) < 0){ + flwd_log(RLOG_LV_FATAL, "Socket bind port %u error, %s!\n", sock_addr_port_host_order + i, strerror(errno)); + return -1; + } + } + + global_dev_handle->io_para.device_ip_net_order = sock_addr_ip_net_order; + global_dev_handle->io_para.socket_port_net_order = htons(sock_addr_port_host_order); + + socket_io_handle->tot_thread_count = global_dev_handle->tot_thread_count; + global_dev_handle->low_level_io_handle = (void *)socket_io_handle; + + return 0; +} + +#if FLWD_NAT_SPORT_VOLATILE +static struct sockaddr_in g_remote_addr; +#endif + + +static int socket_low_level_send(flwd_device_handle_t *global_dev_handle, int tid, void *mbuff) +{ + int ret; + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + flwd_device_handle_socket_t *sock_io_handle = (flwd_device_handle_socket_t *)global_dev_handle->low_level_io_handle; + struct sockaddr_in sockadd; + const flwd_ipv4_hdr_t *ipv4_hdr = (flwd_ipv4_hdr_t *) (sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t)); + const flwd_udp_hdr_t *udph = (flwd_udp_hdr_t *)(sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t)); + + sockadd.sin_family = AF_INET; + +#if FLWD_NAT_SPORT_VOLATILE + sockadd.sin_addr.s_addr = g_remote_addr.sin_addr.s_addr; + sockadd.sin_port = g_remote_addr.sin_port; +#else + sockadd.sin_addr.s_addr = ipv4_hdr->ip_dst.s_addr; + sockadd.sin_port = udph->uh_dport; +#endif + + ret = sendto(sock_io_handle->socket_io_thread_para[tid].sd, + sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t), /* �ϲ�Ӧ�ö�Ĭ�ϴ�mac�㿪ʼ, �˴�ʹ��socketģʽ, ϵͳ���װMAC,IP,UDP, �����vxlan����MACͷ+ipͷ+udpͷ */ + sock_mbuff->data_actual_len - sizeof(flwd_eth_hdr_t) - sizeof(flwd_ipv4_hdr_t) - sizeof(flwd_udp_hdr_t), /* �ϲ�Ӧ�ö�Ĭ�ϴ�mac�㿪ʼ, �˴�ʹ��socketģʽ, ϵͳ���װMAC,IP,UDP, ����vxlan����MACͷ+ipͷ+udpͷ */ + MSG_DONTWAIT, + (const struct sockaddr *)&sockadd, + sizeof(struct sockaddr)); + + return ret; +} + +int low_level_pkt_recv(flwd_device_handle_t *g_dev_handle, int tid, void **mbuff) +{ + int ret; + socket_mbuff_t *sock_mbuff; + char sock_rcv_buf[FLWD_LINK_MTU]; + flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)g_dev_handle->low_level_io_handle; + flwd_eth_hdr_t *ehdr; + flwd_ipv4_hdr_t *ipv4_hdr; + struct sockaddr_in local_remote_addr; + socklen_t addr_len = sizeof(local_remote_addr); + + ret = recvfrom(socket_io_handle->socket_io_thread_para[tid].sd, sock_rcv_buf, FLWD_LINK_MTU, MSG_DONTWAIT, (struct sockaddr *)&local_remote_addr, &addr_len); + + if(ret > 0){ + sock_mbuff = flwd_socket_create_new_mbuff(ret + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t)); + + /* α��һ��mac��ʼ��ԭʼ��, ģ��vxlan���ethernet */ + ehdr = (flwd_eth_hdr_t *)(sock_mbuff->data_actual_ptr); + ehdr->h_proto = htons(ETH_P_IP); + + /* ģ��vxlan���ipv4 */ + ipv4_hdr = (flwd_ipv4_hdr_t *) (sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t)); + ipv4_hdr->ip_v = 4; + ipv4_hdr->ip_hl = 5; + ipv4_hdr->ip_p = IPPROTO_UDP; + + /* ��udp�յ�������Ԥ��ͷ���ռ�, �ٿ��� */ + memcpy(sock_mbuff->data_actual_ptr + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t), sock_rcv_buf, ret); + sock_mbuff->data_actual_len = ret + sizeof(flwd_eth_hdr_t) + sizeof(flwd_ipv4_hdr_t) + sizeof(flwd_udp_hdr_t); + + +#if FLWD_NAT_SPORT_VOLATILE + if(memcmp(&local_remote_addr, &g_remote_addr, sizeof(local_remote_addr)) != 0){ + /* ��ΪNAT�ڲ���������������, ���³�NAT���Դ�˿ڱ��� */ + memcpy(&g_remote_addr, &local_remote_addr,sizeof(local_remote_addr)); + } +#endif + + + }else{ + *mbuff = NULL; + return -1; + } + + *mbuff = (void *)sock_mbuff; + + return ret; +} + +void low_level_pkt_free(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + free(sock_mbuff->__data_buf); + free(sock_mbuff); + + return; +} + +void *low_level_mbuff_malloc(flwd_device_handle_t *g_dev_handle, int tid, int len) +{ + //flwd_device_handle_socket_t *socket_io_handle = (flwd_device_handle_socket_t *)g_dev_handle->low_level_io_handle; + + socket_mbuff_t *mbuff = (socket_mbuff_t *)malloc(sizeof(socket_mbuff_t)); + + mbuff->__data_buf = (char *)malloc(FLWD_LINK_MTU); + mbuff->data_actual_ptr = mbuff->__data_buf + FLWD_VXLAN_OUTER_PACKET_LEN; + mbuff->__data_buf_max_len = FLWD_LINK_MTU; + mbuff->data_actual_len = 0; + + return (void *)mbuff; +} + +char *low_level_mbuff_mtod(void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + return (char *)sock_mbuff->data_actual_ptr; +} + +void low_level_mbuff_free(struct __flwd_device_handle *h, int tid, void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + free(sock_mbuff->__data_buf); + sock_mbuff->data_actual_len = 0; + sock_mbuff->__data_buf_max_len = 0; + free(mbuff); +} + +void low_level_mbuff_free_after_send(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + /* pcapģʽ�������Զ�free, �ٴε���������free���� */ + low_level_mbuff_free(g_dev_handle, tid, mbuff); +} + +void low_level_mbuff_send_back(flwd_device_handle_t *g_dev_handle, int tid, void *mbuff) +{ + /* socketģʽ��ʱ���û�עgdev���ݰ�, �պ��� */ + return; +} + +/* + ��mbuff����user_data����. + return value: + ������ʼλ��; +*/ +char * low_level_mbuff_data_append(void *mbuff, const char *user_data, int user_data_len) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(user_data_len <= sock_mbuff->__data_buf_max_len - sock_mbuff->data_actual_len); + + memcpy(sock_mbuff->data_actual_ptr, user_data, user_data_len); + sock_mbuff->data_actual_len += user_data_len; + + return (char *)sock_mbuff->data_actual_ptr; +} + +/* ����ָ����ǰ�ƶ�N���ֽ�, ���ݳ����Զ�����N, ���������������ݰ�֮ǰ���������ͷ, Ԥ��һЩ�ռ�, ��vxlan */ +char * low_level_mbuff_data_forward(void *mbuff, int n) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(n <= sock_mbuff->data_actual_ptr - sock_mbuff->__data_buf); + + sock_mbuff->data_actual_ptr -= n; + sock_mbuff->data_actual_len += n; + + return (char *)sock_mbuff->data_actual_ptr; +} + + +/* ����ָ������ƶ�N���ֽ�, ���ݳ����Զ�����N, �����ǰ��������ݰ���ijЩ��ͷ����, ���ȥvxlanͷ�� */ +char * low_level_mbuff_data_rearward(void *mbuff, int n) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + assert(n <= sock_mbuff->__data_buf_max_len - sock_mbuff->data_actual_len); + + sock_mbuff->data_actual_ptr += n; + sock_mbuff->data_actual_len -= n; + + return sock_mbuff->data_actual_ptr; +} + + +int low_level_mbuff_get_pkt_len(void *mbuff) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + return sock_mbuff->data_actual_len; +} + +void low_level_mbuff_set_pkt_len(void *mbuff, int pkt_len) +{ + socket_mbuff_t *sock_mbuff = (socket_mbuff_t *)mbuff; + + sock_mbuff->data_actual_len = pkt_len; +} + + +int low_level_send(flwd_device_handle_t *global_dev_handle, int tid, void *mbuff) +{ + return socket_low_level_send(global_dev_handle, tid, mbuff); +} + + +int low_level_io_init(flwd_device_handle_t *global_dev_handle) +{ + return socket_low_level_io_init(global_dev_handle); +} + +#ifdef __cplusplus +} +#endif + |
