1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| if (pfd.revents & POLLIN) { unsigned char *stream = NULL; nty_nic_read(ctx, &stream); nty_eth_process(ctx, stream); }
static int nty_eth_process(nty_nic_context *ctx, unsigned char *stream) {
struct ethhdr *eh = (struct ethhdr*)stream;
if (ntohs(eh->h_proto) == PROTO_IP) { nty_ipv4_process(ctx, stream); } else if (ntohs(eh->h_proto) == PROTO_ARP) { nty_arp_process(ctx, stream); }
return 0; }
int nty_ipv4_process(nty_nic_context *ctx, unsigned char *stream) {
struct iphdr *iph = (struct iphdr*)(stream + sizeof(struct ethhdr)); if (ip_fast_csum(iph, iph->ihl)) return -1;
if (iph->protocol == PROTO_UDP) { nty_udp_process(ctx, stream); } else if (iph->protocol == PROTO_TCP) { nty_tcp_process(ctx, stream); } else if (iph->protocol == PROTO_ICMP) { nty_icmp_process(ctx, stream); } return 0; }
int nty_udp_process(nty_nic_context *ctx, unsigned char *stream) { struct udppkt *udph = (struct udppkt *)stream;
int udp_length = ntohs(udph->udp.len); udph->body[udp_length-8] = '\0'; struct udppkt udph_rt; nty_udp_pkt(udph, &udph_rt); nty_nic_write(ctx, &udph_rt, sizeof(struct udppkt));
return 0; }
void nty_udp_pkt(struct udppkt *udp, struct udppkt *udp_rt) { memcpy(udp_rt, udp, sizeof(struct udppkt));
memcpy(udp_rt->eh.h_dest, udp->eh.h_source, ETH_ALEN); memcpy(udp_rt->eh.h_source, udp->eh.h_dest, ETH_ALEN);
memcpy(&udp_rt->ip.saddr, &udp->ip.daddr, sizeof(udp->ip.saddr)); memcpy(&udp_rt->ip.daddr, &udp->ip.saddr, sizeof(udp->ip.saddr));
memcpy(&udp_rt->udp.source, &udp->udp.dest, sizeof(udp->udp.source)); memcpy(&udp_rt->udp.dest, &udp->udp.source, sizeof(udp->udp.dest)); }
int nty_nic_write(nty_nic_context *ctx, const void *stream, int length) { if (ctx == NULL) return -1; if (stream == NULL) return -2; if (length == 0) return 0; nm_inject(ctx->nmr, stream, length);
return 0; }
|