OpenBCM V1.07b12 (Linux)

Packet Radio Mailbox

DB0FHN

[JN59NK Nuernberg]

 Login: GUEST





  
DL9SAU > WAMPES   15.09.01 16: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


 18.05.2024 17:51:45lGo back Go up