1 #define __MOS_CORE_ 2 3 #include <string.h> 4 #include <netinet/ip.h> 5 #include <stdbool.h> 6 7 #include "ip_in.h" 8 #include "ip_out.h" 9 #include "tcp.h" 10 #include "mtcp_api.h" 11 #include "debug.h" 12 #include "mos_api.h" 13 #include "icmp.h" 14 #include "config.h" 15 16 #define ETH_P_IP_FRAG 0xF800 17 #define ETH_P_IPV6_FRAG 0xF6DD 18 19 20 /*----------------------------------------------------------------------------*/ 21 inline void 22 FillInPacketIPContext (struct pkt_ctx *pctx, struct iphdr *iph, int ip_len) 23 { 24 pctx->p.iph = iph; 25 pctx->p.ip_len = ip_len; 26 27 return; 28 } 29 /*----------------------------------------------------------------------------*/ 30 inline int 31 ProcessInIPv4Packet(mtcp_manager_t mtcp, struct pkt_ctx *pctx) 32 { 33 bool release = false; 34 int ret; 35 struct mon_listener *walk; 36 /* check and process IPv4 packets */ 37 struct iphdr* iph = 38 (struct iphdr *)((char *)pctx->p.ethh + sizeof(struct ethhdr)); 39 int ip_len = ntohs(iph->tot_len); 40 41 /* drop the packet shorter than ip header */ 42 if (ip_len < sizeof(struct iphdr)) { 43 ret = ERROR; 44 goto __return; 45 } 46 47 if (iph->version != IPVERSION ) { 48 release = true; 49 ret = FALSE; 50 goto __return; 51 } 52 53 FillInPacketIPContext(pctx, iph, ip_len); 54 55 /* callback for monitor raw socket */ 56 TAILQ_FOREACH(walk, &mtcp->monitors, link) 57 if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW) { 58 if (ISSET_BPFFILTER(walk->raw_pkt_fcode) && 59 EVAL_BPFFILTER(walk->raw_pkt_fcode, (uint8_t *)pctx->p.ethh, 60 pctx->p.eth_len)) 61 HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH, 62 pctx, MOS_ON_PKT_IN); 63 } 64 65 /* if there is no MOS_SOCK_STREAM or MOS_SOCK_MONITOR_STREAM socket, 66 forward IP packet before reaching upper (transport) layer */ 67 if (mtcp->num_msp == 0 && mtcp->num_esp == 0) { 68 if (pctx->forward) { 69 ForwardIPPacket(mtcp, pctx); 70 } 71 return TRUE; 72 } 73 74 if (ip_fast_csum(iph, iph->ihl)) { 75 ret = ERROR; 76 goto __return; 77 } 78 79 switch (iph->protocol) { 80 case IPPROTO_TCP: 81 return ProcessInTCPPacket(mtcp, pctx); 82 case IPPROTO_ICMP: 83 if (ProcessICMPPacket(mtcp, pctx)) 84 return TRUE; 85 default: 86 /* forward other protocols without any processing */ 87 if (!mtcp->num_msp || !pctx->forward) 88 release = true; 89 else 90 ForwardIPPacket(mtcp, pctx); 91 92 ret = FALSE; 93 goto __return; 94 } 95 96 __return: 97 if (release && mtcp->iom->release_pkt) 98 mtcp->iom->release_pkt(mtcp->ctx, pctx->p.in_ifidx, 99 (unsigned char *)pctx->p.ethh, pctx->p.eth_len); 100 return ret; 101 } 102 /*----------------------------------------------------------------------------*/ 103