[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-bridge
Subject: Re: [Bridge] Bridging between user processes - TAP question
From: Stephen Hemminger <shemminger () osdl ! org>
Date: 2004-06-17 22:52:05
Message-ID: 20040617155205.38b9dbff () dell_ss3 ! pdx ! osdl ! net
[Download RAW message or body]
Do either of these help? I used them about a year ago when updating
tun and tap to new netdevice model.
["taptest.c" (text/plain)]
/* 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;
}
["taptest.c" (application/octet-stream)]
/* 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;
}
_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic