Do either of these help? I used them about a year ago when updating tun and tap to new netdevice model. -------------- next part -------------- /* Simple program to listen to /dev/tap0 and reply to pings. */ #include <fcntl.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #if defined(__GLIBC__) && (__GLIBC__ == 2) #include <netinet/tcp.h> #include <netinet/udp.h> #else #include <linux/tcp.h> #include <linux/udp.h> #endif #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> u_int16_t csum_partial(void *buffer, unsigned int len, u_int16_t prevsum) { u_int32_t sum = 0; u_int16_t *ptr = buffer; while (len > 1) { sum += *ptr++; len -= 2; } if (len) { union { u_int8_t byte; u_int16_t wyde; } odd; odd.wyde = 0; odd.byte = *((u_int8_t *)ptr); sum += odd.wyde; } sum = (sum >> 16) + (sum & 0xFFFF); sum += prevsum; return (sum + (sum >> 16)); } int main() { int fd, len; union { struct { char etherhdr[16]; struct iphdr ip; } fmt; unsigned char raw[65536]; } u; fd = open("/dev/tap0", O_RDWR); if (fd < 0) { perror("Opening `/dev/tap0'"); return 1; } /* u.fmt.ip.ihl in host order! Film at 11. */ while ((len = read(fd, &u, sizeof(u))) > 0) { u_int32_t tmp; struct icmphdr *icmp = (void *)((u_int32_t *)&u.fmt.ip + u.fmt.ip.ihl ); struct tcphdr *tcp = (void *)icmp; struct udphdr *udp = (void *)icmp; fprintf(stderr, "SRC = %u.%u.%u.%u DST = %u.%u.%u.%u\n", (ntohl(u.fmt.ip.saddr) >> 24) & 0xFF, (ntohl(u.fmt.ip.saddr) >> 16) & 0xFF, (ntohl(u.fmt.ip.saddr) >> 8) & 0xFF, (ntohl(u.fmt.ip.saddr) >> 0) & 0xFF, (ntohl(u.fmt.ip.daddr) >> 24) & 0xFF, (ntohl(u.fmt.ip.daddr) >> 16) & 0xFF, (ntohl(u.fmt.ip.daddr) >> 8) & 0xFF, (ntohl(u.fmt.ip.daddr) >> 0) & 0xFF); switch (u.fmt.ip.protocol) { case IPPROTO_ICMP: if (icmp->type == ICMP_ECHO) { fprintf(stderr, "PONG! (iphdr = %u bytes)\n", (unsigned int)((char *)icmp - (char *)&u.fmt.ip)); /* Turn it around */ tmp = u.fmt.ip.saddr; u.fmt.ip.saddr = u.fmt.ip.daddr; u.fmt.ip.daddr = tmp; icmp->type = ICMP_ECHOREPLY; icmp->checksum = 0; icmp->checksum = ~csum_partial(icmp, ntohs(u.fmt.ip.tot_len) - u.fmt.ip.ihl*4, 0); { unsigned int i; for (i = 44; i < ntohs(u.fmt.ip.tot_len); i++){ printf("%u:0x%02X ", i, ((unsigned char *) &u.fmt.ip)[i]); } printf("\n"); } write(fd, &u, len); } break; case IPPROTO_TCP: fprintf(stderr, "TCP: %u -> %u\n", ntohs(tcp->source), ntohs(tcp->dest)); break; case IPPROTO_UDP: fprintf(stderr, "UDP: %u -> %u\n", ntohs(udp->source), ntohs(udp->dest)); break; } } if (len < 0) perror("Reading from `/dev/tap0'"); else fprintf(stderr, "Empty read from `/dev/tap0'"); return len < 0 ? 1 : 0; } -------------- next part -------------- A non-text attachment was scrubbed... Name: taptest.c Type: application/octet-stream Size: 2748 bytes Desc: not available Url : http://lists.osdl.org/pipermail/bridge/attachments/20040617/370cb719/taptest.obj