176404edcSAsim Jamshed #include <stdio.h>
276404edcSAsim Jamshed
376404edcSAsim Jamshed #include <stdint.h>
476404edcSAsim Jamshed #include <stdlib.h>
576404edcSAsim Jamshed #include <unistd.h>
676404edcSAsim Jamshed #include <assert.h>
776404edcSAsim Jamshed
876404edcSAsim Jamshed #ifdef DARWIN
976404edcSAsim Jamshed #include <netinet/if_ether.h>
1076404edcSAsim Jamshed #include <netinet/tcp.h>
1176404edcSAsim Jamshed #else
1276404edcSAsim Jamshed #include <linux/if_ether.h>
1376404edcSAsim Jamshed #include <linux/tcp.h>
1476404edcSAsim Jamshed #endif
1576404edcSAsim Jamshed #include <string.h>
1676404edcSAsim Jamshed #include <netinet/ip.h>
1776404edcSAsim Jamshed
1876404edcSAsim Jamshed #include "mtcp.h"
1976404edcSAsim Jamshed #include "arp.h"
2076404edcSAsim Jamshed #include "eth_out.h"
2176404edcSAsim Jamshed #include "debug.h"
2276404edcSAsim Jamshed #include "mos_api.h"
2376404edcSAsim Jamshed #include "config.h"
2476404edcSAsim Jamshed
2576404edcSAsim Jamshed #ifndef TRUE
2676404edcSAsim Jamshed #define TRUE (1)
2776404edcSAsim Jamshed #endif
2876404edcSAsim Jamshed
2976404edcSAsim Jamshed #ifndef FALSE
3076404edcSAsim Jamshed #define FALSE (0)
3176404edcSAsim Jamshed #endif
3276404edcSAsim Jamshed
3376404edcSAsim Jamshed #ifndef ERROR
3476404edcSAsim Jamshed #define ERROR (-1)
3576404edcSAsim Jamshed #endif
3676404edcSAsim Jamshed
3776404edcSAsim Jamshed #define MAX(a, b) ((a)>(b)?(a):(b))
3876404edcSAsim Jamshed #define MIN(a, b) ((a)<(b)?(a):(b))
3976404edcSAsim Jamshed
4076404edcSAsim Jamshed #define MAX_WINDOW_SIZE 65535
4176404edcSAsim Jamshed
4276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
4376404edcSAsim Jamshed enum ETH_BUFFER_RETURN {BUF_RET_MAYBE, BUF_RET_ALWAYS};
4476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
4576404edcSAsim Jamshed int
FlushSendChunkBuf(mtcp_manager_t mtcp,int nif)4676404edcSAsim Jamshed FlushSendChunkBuf(mtcp_manager_t mtcp, int nif)
4776404edcSAsim Jamshed {
4876404edcSAsim Jamshed return 0;
4976404edcSAsim Jamshed }
5076404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
5176404edcSAsim Jamshed inline void
FillOutPacketEthContext(struct pkt_ctx * pctx,uint32_t cur_ts,int out_ifidx,struct ethhdr * ethh,int eth_len)5276404edcSAsim Jamshed FillOutPacketEthContext(struct pkt_ctx *pctx, uint32_t cur_ts, int out_ifidx,
5376404edcSAsim Jamshed struct ethhdr *ethh, int eth_len)
5476404edcSAsim Jamshed {
5576404edcSAsim Jamshed pctx->p.cur_ts = cur_ts;
56*a834ea89SAsim Jamshed pctx->p.in_ifidx = -1;
5776404edcSAsim Jamshed pctx->out_ifidx = out_ifidx;
5876404edcSAsim Jamshed pctx->p.ethh = ethh;
5976404edcSAsim Jamshed pctx->p.eth_len = eth_len;
6076404edcSAsim Jamshed }
6176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
6276404edcSAsim Jamshed uint8_t *
EthernetOutput(struct mtcp_manager * mtcp,struct pkt_ctx * pctx,uint16_t h_proto,int nif,unsigned char * dst_haddr,uint16_t iplen,uint32_t cur_ts)6376404edcSAsim Jamshed EthernetOutput(struct mtcp_manager *mtcp, struct pkt_ctx *pctx,
6476404edcSAsim Jamshed uint16_t h_proto, int nif, unsigned char* dst_haddr, uint16_t iplen,
6576404edcSAsim Jamshed uint32_t cur_ts)
6676404edcSAsim Jamshed {
6776404edcSAsim Jamshed uint8_t *buf;
6876404edcSAsim Jamshed struct ethhdr *ethh;
6976404edcSAsim Jamshed int i;
707631e025SAsim Jamshed
71a5e1a556SAsim Jamshed /*
72a5e1a556SAsim Jamshed * -sanity check-
73a5e1a556SAsim Jamshed * return early if no interface is set (if routing entry does not exist)
74a5e1a556SAsim Jamshed */
75a5e1a556SAsim Jamshed if (nif < 0) {
76a5e1a556SAsim Jamshed TRACE_INFO("No interface set!\n");
77a5e1a556SAsim Jamshed return NULL;
78a5e1a556SAsim Jamshed }
797631e025SAsim Jamshed
8076404edcSAsim Jamshed if (!mtcp->iom->get_wptr) {
8176404edcSAsim Jamshed TRACE_INFO("get_wptr() in io_module is undefined.");
8276404edcSAsim Jamshed return NULL;
8376404edcSAsim Jamshed }
8476404edcSAsim Jamshed buf = mtcp->iom->get_wptr(mtcp->ctx, nif, iplen + ETHERNET_HEADER_LEN);
8576404edcSAsim Jamshed if (!buf) {
8676404edcSAsim Jamshed TRACE_DBG("Failed to get available write buffer\n");
8776404edcSAsim Jamshed return NULL;
8876404edcSAsim Jamshed }
8976404edcSAsim Jamshed
9076404edcSAsim Jamshed ethh = (struct ethhdr *)buf;
9176404edcSAsim Jamshed for (i = 0; i < ETH_ALEN; i++) {
9276404edcSAsim Jamshed ethh->h_source[i] = g_config.mos->netdev_table->ent[nif]->haddr[i];
9376404edcSAsim Jamshed ethh->h_dest[i] = dst_haddr[i];
9476404edcSAsim Jamshed }
9576404edcSAsim Jamshed ethh->h_proto = htons(h_proto);
9676404edcSAsim Jamshed
9776404edcSAsim Jamshed if (pctx)
9876404edcSAsim Jamshed FillOutPacketEthContext(pctx, cur_ts, nif,
9976404edcSAsim Jamshed ethh, iplen + ETHERNET_HEADER_LEN);
10076404edcSAsim Jamshed
10176404edcSAsim Jamshed return (uint8_t *)(ethh + 1);
10276404edcSAsim Jamshed }
10376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
10476404edcSAsim Jamshed void
ForwardEthernetFrame(struct mtcp_manager * mtcp,struct pkt_ctx * pctx)10576404edcSAsim Jamshed ForwardEthernetFrame(struct mtcp_manager *mtcp, struct pkt_ctx *pctx)
10676404edcSAsim Jamshed {
10776404edcSAsim Jamshed uint8_t *buf;
10876404edcSAsim Jamshed
10976404edcSAsim Jamshed if (g_config.mos->nic_forward_table != NULL) {
11076404edcSAsim Jamshed pctx->out_ifidx =
111*a834ea89SAsim Jamshed g_config.mos->nic_forward_table->nic_fwd_table[pctx->p.in_ifidx];
11276404edcSAsim Jamshed
11376404edcSAsim Jamshed if (pctx->out_ifidx == -1) {
11476404edcSAsim Jamshed TRACE_DBG("Could not find outgoing index (index)!\n");
11576404edcSAsim Jamshed return;
11676404edcSAsim Jamshed }
11776404edcSAsim Jamshed
11876404edcSAsim Jamshed if (!mtcp->iom->get_wptr) {
11976404edcSAsim Jamshed TRACE_INFO("get_wptr() in io_module is undefined.");
12076404edcSAsim Jamshed return;
12176404edcSAsim Jamshed }
12276404edcSAsim Jamshed
12376404edcSAsim Jamshed buf = mtcp->iom->get_wptr(mtcp->ctx, pctx->out_ifidx, pctx->p.eth_len);
12476404edcSAsim Jamshed
12576404edcSAsim Jamshed if (!buf) {
12676404edcSAsim Jamshed TRACE_DBG("Failed to get available write buffer\n");
12776404edcSAsim Jamshed return;
12876404edcSAsim Jamshed }
12976404edcSAsim Jamshed
13076404edcSAsim Jamshed memcpy(buf, pctx->p.ethh, pctx->p.eth_len);
13176404edcSAsim Jamshed } else {
13276404edcSAsim Jamshed TRACE_DBG("Ethernet forwarding table entry does not exist.\n");
13376404edcSAsim Jamshed }
13476404edcSAsim Jamshed }
13576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
136