|
DL9SAU > WAMPES 15.09.01 15:37l 402 Lines 11240 Bytes #999 (0) @ DL
BID : DB0TUDGJPKEM
Read: GUEST DK5SG DM3TT
Subj: update: wampes: krnlif.c PF_PACKET fix fuer linux 2.2.x ..
Path: DB0ROF<DB0ERF<DB0ABZ<DB0UHI<DB0FC<DB0TUD
Sent: 010915/1433z @:DB0TUD.#SAX.DEU.EU [TCP/IP-NODE DRESDEN] DP6.00 $:DB0TUDGJ
der patch aus BID $DB0TUDGJPDPO / $DB0TUDGJPDPP war leider noch sehr
unschoen. war wohl etwas uebermuedet.
ich erlaube mir deshalb, ihn hier nochmal in ueberarbeiteter
fassung einzuspielen. sorry..
73,
- thomas
*** src/krnlif.c.orig Sun Jun 20 21:03:51 1999
--- src/krnlif.c Sat Sep 15 16:17:00 2001
***************
*** 1,4 ****
! /* @(#) $Id: krnlif.c,v 1.8 1999/06/20 19:03:51 deyke Exp $ */
#if defined linux
--- 1,4 ----
! /* @(#) $Id: krnlif.c,v 1.8.2.6 2001/09/15 14:09:33 dl9sau Exp $ */
#if defined linux
***************
*** 57,64 ****
--- 57,79 ----
*
* This module is Linux specific. SOCK_PACKET is the Linux way to get
* packets at the raw interface level.
+ *
+ * -D USE_OBSOLETE_SOCK_PACKET because of incompatibilties with kernel 2.2.x
+ * by thomas <dl9sau>
*/
+ #include <linux/version.h>
+ #ifndef KERNEL_VERSION
+ #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+ #endif
+ #ifndef LINUX_VERSION_CODE
+ #define LINUX_VERSION_CODE KERNEL_VERSION(2,0,0)-1
+ #endif
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+ #define USE_OBSOLETE_SOCK_PACKET 1
+ #endif
+
#include <sys/types.h>
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
***************
*** 72,78 ****
--- 87,105 ----
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/in.h>
+ #ifndef USE_OBSOLETE_SOCK_PACKET
+ #include <features.h> /* for the glibc version number */
+ #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
+ #include <netpacket/packet.h>
+ #include <net/ethernet.h> /* the L2 protocols */
+ #else
+ #include <asm/types.h>
+ #include <linux/if_packet.h>
+ #include <linux/if_ether.h> /* The L2 protocols */
+ #endif
+ #endif
#include <unistd.h>
+ #include <fcntl.h>
#include "global.h"
#include "mbuf.h"
***************
*** 97,102 ****
--- 124,132 ----
struct mbuf *sndq; /* Transmit queue */
short oldflags; /* used to restore the interrupt flags */
+ #ifndef USE_OBSOLETE_SOCK_PACKET
+ int ifindex; /* interface index (ifr_ifru.ifru_ivalue) */
+ #endif
int proto; /* protocol to listen for */
int promisc; /* set interface to promiscious mode */
***************
*** 113,137 ****
static int krnlif_up(struct krnlif *ki)
{
struct ifreq ifr;
struct sockaddr sa;
if (ki->fd >= 0) /* Already UP */
return 0;
! if ((ki->fd = socket(PF_INET, SOCK_PACKET, ki->proto)) < 0)
goto Fail;
strcpy(ifr.ifr_name, ki->iface->name);
! if (ioctl(ki->fd, SIOCGIFFLAGS, &ifr) < 0)
goto Fail;
ki->oldflags = ifr.ifr_flags;
ifr.ifr_flags |= IFF_UP;
if (ki->promisc)
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(ki->fd, SIOCSIFFLAGS, &ifr) < 0)
goto Fail;
! strcpy(sa.sa_data, ki->iface->name);
! sa.sa_family = AF_INET;
! if (bind(ki->fd, &sa, sizeof(struct sockaddr)) < 0)
! goto Fail;
on_read(ki->fd, (void (*)(void *)) ki->iface->rxproc, ki->iface);
return 0;
--- 143,202 ----
static int krnlif_up(struct krnlif *ki)
{
struct ifreq ifr;
+ #ifdef USE_OBSOLETE_SOCK_PACKET
struct sockaddr sa;
+ #else
+ struct sockaddr_ll sll;
+ struct packet_mreq mr;
+ #endif
if (ki->fd >= 0) /* Already UP */
return 0;
! #ifdef USE_OBSOLETE_SOCK_PACKET
! if ((ki->fd = socket(PF_INET, SOCK_PACKET, ki->proto)) < 0) {
! #else
! if ((ki->fd = socket(PF_PACKET, SOCK_RAW, ki->proto)) < 0) {
! #endif
! printf("error in krnlif_up: socket() for %s failed. this should never happen\n", ki->proto);
goto Fail;
+ }
strcpy(ifr.ifr_name, ki->iface->name);
! if (ioctl(ki->fd, SIOCGIFFLAGS, &ifr) < 0) {
! printf("error in krnlif_up: ioctl(SIOCGIFFLAGS) for %s failed. this should never happen\n", ki->iface->name);
goto Fail;
+ }
ki->oldflags = ifr.ifr_flags;
ifr.ifr_flags |= IFF_UP;
if (ki->promisc)
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(ki->fd, SIOCSIFFLAGS, &ifr) < 0)
+ goto Fail;
+ #ifdef USE_OBSOLETE_SOCK_PACKET
+ strcpy(sa.sa_data, ki->iface->name);
+ sa.sa_family = AF_INET;
+ if (bind(ki->fd, &sa, sizeof(struct sockaddr)) < 0)
+ goto Fail;
+ #else
+ memset(&sll, 0, sizeof(sll));
+ sll.sll_ifindex = ki->ifindex;
+ sll.sll_protocol = ki->proto;
+ sll.sll_family = AF_PACKET;
+ if (bind(ki->fd, (struct sockaddr *) &sll, sizeof(sll)) < 0) {
+ printf("error in krnlif_up: bind() for %s failed. this should never happen.\ndebug: Error %s (%i)\n", ki->iface->name, strerror(errno), errno);
goto Fail;
! }
! memset(&mr, 0, sizeof(&mr));
! mr.mr_ifindex = sll.sll_ifindex;
! if (ki->promisc) {
! mr.mr_type = PACKET_MR_PROMISC;
! }
! if (setsockopt(ki->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (char *) &mr, sizeof(mr)) < 0) {
! perror("PACKET_ADD_MEMBERSHIP");
! printf("error in krnlif_up: setsockopt(SOL_PACKET, PACKET_ADD_MEMBERSHIP) for %s (%d) failed: %s (%i). this should never happen\n", ki->iface->name, ki->ifindex, strerror(errno), errno);
! goto Fail;
! }
! fcntl(ki->fd, F_SETFL, fcntl(ki->fd, F_GETFL, 0) | O_NONBLOCK);
! #endif
on_read(ki->fd, (void (*)(void *)) ki->iface->rxproc, ki->iface);
return 0;
***************
*** 203,224 ****
for (bp = ki->sndq; bp; bp = bp->next) {
cnt += bp->cnt;
if (cnt > sizeof(buf)) {
! free_mbuf(&ki->sndq);
return;
}
memcpy(bufp, bp->data, bp->cnt);
bufp += bp->cnt;
}
strncpy(to.sa_data, ki->iface->name, sizeof(to.sa_data));
i = sendto(ki->fd, buf, cnt, 0, &to, sizeof(to));
if (i >= 0) {
ki->txpkts++;
ki->txchar += cnt;
! free_mbuf(&ki->sndq);
return;
}
if (errno == EMSGSIZE) {
! free_mbuf(&ki->sndq);
return;
}
if (errno == EWOULDBLOCK)
--- 268,303 ----
for (bp = ki->sndq; bp; bp = bp->next) {
cnt += bp->cnt;
if (cnt > sizeof(buf)) {
! /* dl9sau bugfix: free_p() to free this packet,
! * not free_mbuf(), because ki->sndq must point to the
! * next packet (anext) or point to 0 when no packet
! * is left in the sendqueue.
! */
! free_p(&ki->sndq);
return;
}
memcpy(bufp, bp->data, bp->cnt);
bufp += bp->cnt;
}
+ #ifdef USE_OBSOLETE_SOCK_PACKET
strncpy(to.sa_data, ki->iface->name, sizeof(to.sa_data));
i = sendto(ki->fd, buf, cnt, 0, &to, sizeof(to));
+ #else
+ /* puh.. thanks to sockaddr_ll, the socket knows about the iface,
+ * and NULL is enough..
+ */
+ i = sendto(ki->fd, buf, cnt, 0, NULL, 0);
+ #endif
if (i >= 0) {
ki->txpkts++;
ki->txchar += cnt;
! free_p(&ki->sndq);
return;
}
+ perror("krnlif_tx(): sendto()");
+ printf("debug: krnlif_tx: sendto() returned %d\n", i);
if (errno == EMSGSIZE) {
! free_p(&ki->sndq);
return;
}
if (errno == EWOULDBLOCK)
***************
*** 263,279 ****
int from_len = sizeof(from);
int i;
struct mbuf *bp;
if (!iface || iface->dev < 0 || iface->dev >= KRNLIF_MAX)
return;
ki = KrnlIf + iface->dev;
if (!(bp = alloc_mbuf(ki->iface->mtu+16)))
return;
i = recvfrom(ki->fd, bp->data, bp->size, 0, &from, &from_len);
if (i <= 0) {
- if (i < 0 || errno != EWOULDBLOCK)
- krnlif_down(ki);
free_mbuf(&bp);
return;
}
bp->cnt = i;
--- 342,385 ----
int from_len = sizeof(from);
int i;
struct mbuf *bp;
+ int j;
if (!iface || iface->dev < 0 || iface->dev >= KRNLIF_MAX)
return;
ki = KrnlIf + iface->dev;
if (!(bp = alloc_mbuf(ki->iface->mtu+16)))
return;
+ #ifdef USE_OBSOLETE_SOCK_PACKET
i = recvfrom(ki->fd, bp->data, bp->size, 0, &from, &from_len);
+ #else
+ i = recvfrom(ki->fd, bp->data, bp->size, 0, NULL, 0);
+ #endif
+ if (i >= 0 && i < 1+AXALEN*2+1) {
+ /* kiss-byte + AX25 frame: is minimal 1+(6call+1pid)*2 + Control-Byte */
+ #ifdef notdef
+ // debug: dump non ax25-kiss frames
+ printf("frame dropped: read %d bytes - ", i);
+ printf("bp->data: >");
+ for (j = 0; j < i; j++) {
+ printf("%d: 0x%02x", j, bp->data[j]);
+ if (j < i-1)
+ printf(", ");
+ }
+ printf("<\n");
+ #else
+ // discard silently
+ // debug: printf("warning: read %d bytes. should never happen\n", i);
+ #endif
+ free_mbuf(&bp);
+ return;
+ }
+
if (i <= 0) {
free_mbuf(&bp);
+ if (i < 0 || errno != EWOULDBLOCK) {
+ printf("warning: read %d bytes, cause %s (%i)\n", i, strerror(errno), errno);
+ krnlif_down(ki);
+ }
return;
}
bp->cnt = i;
***************
*** 338,357 ****
struct ifreq ifr;
struct sockaddr hw;
struct sockaddr_in in;
! int fd;
struct hwencap *hwe = hwencap;
if (if_lookup(argv[1]) != NULL) {
! printf("Interface %s already exists\n",argv[4]);
return -1;
}
/*
* get parameters of the interface
*/
if ((fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
perror("socket");
return -1;
}
strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
--- 444,471 ----
struct ifreq ifr;
struct sockaddr hw;
struct sockaddr_in in;
! #ifndef USE_OBSOLETE_SOCK_PACKET
! struct ifreq ifr_h;
! #endif
struct hwencap *hwe = hwencap;
+ int fd;
if (if_lookup(argv[1]) != NULL) {
! printf("Interface %s already exists\n",argv[1]);
return -1;
}
/*
* get parameters of the interface
*/
+ #ifdef USE_OBSOLETE_SOCK_PACKET
if ((fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
+ #else
+ if ((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_AX25))) < 0) {
+ #endif
perror("socket");
return -1;
}
+
strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
***************
*** 364,369 ****
--- 478,484 ----
in.sin_family);
return -1;
}
+ #ifdef USE_OBSOLETE_SOCK_PACKET
memcpy(&in, &ifr.ifr_addr, sizeof(in));
ifr.ifr_addr.sa_family = AF_UNSPEC;
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
***************
*** 371,376 ****
--- 486,506 ----
printf("cannot get hw addr for interface %s\n", argv[1]);
return -1;
}
+ #endif
+ #ifndef USE_OBSOLETE_SOCK_PACKET
+ strncpy(ifr_h.ifr_name, argv[1], sizeof(ifr_h.ifr_name));
+ if (ioctl(fd, SIOCGIFINDEX, &ifr_h) < 0) {
+ perror("ioctl (SIOCGIFINDEX)");
+ printf("cannot get index of interface %s\n", argv[1]);
+ return -1;
+ }
+ strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
+ perror("ioctl (SIOCGIHWADDR)");
+ printf("cannot get hw addr for interface %s\n", argv[1]);
+ return -1;
+ }
+ #endif
hw = ifr.ifr_hwaddr;
for (; (hwe->family != hw.sa_family) && (hwe->encap != NULL); hwe++);
if (hwe->family != hw.sa_family) {
***************
*** 390,395 ****
--- 520,526 ----
printf("Too many kernel interfaces\n");
return -1;
}
+
ki = KrnlIf+dev;
/* Create interface structure and fill in details */
ifp = (struct iface *)callocw(1,sizeof(struct iface));
***************
*** 415,420 ****
--- 546,554 ----
ki->fd = -1;
ki->iface = ifp;
+ #ifndef USE_OBSOLETE_SOCK_PACKET
+ ki->ifindex = ifr_h.ifr_ifindex;
+ #endif
ki->proto = htons(ETH_P_AX25);
ki->promisc = !((argc >= 3) && !strcmp(argv[2], "nopromisc"));;
Read previous mail | Read next mail
| |