1 #include <stdio.h> 2 3 #include <stdint.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 #include <assert.h> 7 8 #ifdef DARWIN 9 #include <netinet/if_ether.h> 10 #include <netinet/tcp.h> 11 #else 12 #include <linux/if_ether.h> 13 #include <linux/tcp.h> 14 #endif 15 #include <string.h> 16 #include <netinet/ip.h> 17 18 #include "mtcp.h" 19 #include "arp.h" 20 #include "eth_out.h" 21 #include "debug.h" 22 #include "mos_api.h" 23 #include "config.h" 24 25 #ifndef TRUE 26 #define TRUE (1) 27 #endif 28 29 #ifndef FALSE 30 #define FALSE (0) 31 #endif 32 33 #ifndef ERROR 34 #define ERROR (-1) 35 #endif 36 37 #define MAX(a, b) ((a)>(b)?(a):(b)) 38 #define MIN(a, b) ((a)<(b)?(a):(b)) 39 40 #define MAX_WINDOW_SIZE 65535 41 42 /*----------------------------------------------------------------------------*/ 43 enum ETH_BUFFER_RETURN {BUF_RET_MAYBE, BUF_RET_ALWAYS}; 44 /*----------------------------------------------------------------------------*/ 45 int 46 FlushSendChunkBuf(mtcp_manager_t mtcp, int nif) 47 { 48 return 0; 49 } 50 /*----------------------------------------------------------------------------*/ 51 inline void 52 FillOutPacketEthContext(struct pkt_ctx *pctx, uint32_t cur_ts, int out_ifidx, 53 struct ethhdr *ethh, int eth_len) 54 { 55 pctx->p.cur_ts = cur_ts; 56 pctx->in_ifidx = -1; 57 pctx->out_ifidx = out_ifidx; 58 pctx->p.ethh = ethh; 59 pctx->p.eth_len = eth_len; 60 } 61 /*----------------------------------------------------------------------------*/ 62 uint8_t * 63 EthernetOutput(struct mtcp_manager *mtcp, struct pkt_ctx *pctx, 64 uint16_t h_proto, int nif, unsigned char* dst_haddr, uint16_t iplen, 65 uint32_t cur_ts) 66 { 67 uint8_t *buf; 68 struct ethhdr *ethh; 69 int i; 70 71 /* 72 * -sanity check- 73 * return early if no interface is set (if routing entry does not exist) 74 */ 75 if (nif < 0) { 76 TRACE_INFO("No interface set!\n"); 77 return NULL; 78 } 79 80 if (!mtcp->iom->get_wptr) { 81 TRACE_INFO("get_wptr() in io_module is undefined."); 82 return NULL; 83 } 84 buf = mtcp->iom->get_wptr(mtcp->ctx, nif, iplen + ETHERNET_HEADER_LEN); 85 if (!buf) { 86 TRACE_DBG("Failed to get available write buffer\n"); 87 return NULL; 88 } 89 90 ethh = (struct ethhdr *)buf; 91 for (i = 0; i < ETH_ALEN; i++) { 92 ethh->h_source[i] = g_config.mos->netdev_table->ent[nif]->haddr[i]; 93 ethh->h_dest[i] = dst_haddr[i]; 94 } 95 ethh->h_proto = htons(h_proto); 96 97 if (pctx) 98 FillOutPacketEthContext(pctx, cur_ts, nif, 99 ethh, iplen + ETHERNET_HEADER_LEN); 100 101 return (uint8_t *)(ethh + 1); 102 } 103 /*----------------------------------------------------------------------------*/ 104 void 105 ForwardEthernetFrame(struct mtcp_manager *mtcp, struct pkt_ctx *pctx) 106 { 107 uint8_t *buf; 108 109 if (g_config.mos->nic_forward_table != NULL) { 110 pctx->out_ifidx = 111 g_config.mos->nic_forward_table->nic_fwd_table[pctx->in_ifidx]; 112 113 if (pctx->out_ifidx == -1) { 114 TRACE_DBG("Could not find outgoing index (index)!\n"); 115 return; 116 } 117 118 if (!mtcp->iom->get_wptr) { 119 TRACE_INFO("get_wptr() in io_module is undefined."); 120 return; 121 } 122 123 buf = mtcp->iom->get_wptr(mtcp->ctx, pctx->out_ifidx, pctx->p.eth_len); 124 125 if (!buf) { 126 TRACE_DBG("Failed to get available write buffer\n"); 127 return; 128 } 129 130 memcpy(buf, pctx->p.ethh, pctx->p.eth_len); 131 } else { 132 TRACE_DBG("Ethernet forwarding table entry does not exist.\n"); 133 } 134 } 135 /*----------------------------------------------------------------------------*/ 136