summaryrefslogtreecommitdiff
path: root/src/packet_io/flwd_packet_io_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/packet_io/flwd_packet_io_socket.c')
-rw-r--r--src/packet_io/flwd_packet_io_socket.c376
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
+