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 (ip_fast_csum(iph, iph->ihl)) { 48 ret = ERROR; 49 goto __return; 50 } 51 52 if (iph->version != IPVERSION ) { 53 release = true; 54 ret = FALSE; 55 goto __return; 56 } 57 58 FillInPacketIPContext(pctx, iph, ip_len); 59 60 switch (iph->protocol) { 61 case IPPROTO_TCP: 62 return ProcessInTCPPacket(mtcp, pctx); 63 case IPPROTO_ICMP: 64 if (ProcessICMPPacket(mtcp, pctx)) 65 return TRUE; 66 default: 67 /* forward other protocols without any processing */ 68 if (!mtcp->num_msp || !pctx->forward) 69 release = true; 70 else 71 ForwardIPPacket(mtcp, pctx); 72 73 ret = FALSE; 74 goto __return; 75 } 76 77 __return: 78 /* callback for monitor raw socket */ 79 TAILQ_FOREACH(walk, &mtcp->monitors, link) 80 if (walk->socket->socktype == MOS_SOCK_MONITOR_RAW) 81 HandleCallback(mtcp, MOS_NULL, walk->socket, MOS_SIDE_BOTH, 82 pctx, MOS_ON_PKT_IN); 83 if (release && mtcp->iom->release_pkt) 84 mtcp->iom->release_pkt(mtcp->ctx, pctx->in_ifidx, 85 (unsigned char *)pctx->p.ethh, pctx->p.eth_len); 86 return ret; 87 } 88 /*----------------------------------------------------------------------------*/ 89