Do either of these help?  I used them about a year ago when updating
tun and tap to new netdevice model.

/* 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;
}
                        

Attachment: taptest.c
Description: Binary data

_______________________________________________
Bridge mailing list
[EMAIL PROTECTED]
http://lists.osdl.org/mailman/listinfo/bridge

Reply via email to