summaryrefslogtreecommitdiff
path: root/package/mopd/src/common/pf-linux2.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/mopd/src/common/pf-linux2.c')
-rw-r--r--package/mopd/src/common/pf-linux2.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/package/mopd/src/common/pf-linux2.c b/package/mopd/src/common/pf-linux2.c
new file mode 100644
index 000000000..1ae82ff90
--- /dev/null
+++ b/package/mopd/src/common/pf-linux2.c
@@ -0,0 +1,321 @@
+/*
+ * General Purpose AppleTalk Packet Filter Interface
+ *
+ * Copyright (c) 1992-1995, The University of Melbourne.
+ * All Rights Reserved. Permission to redistribute or
+ * use any part of this software for any purpose must
+ * be obtained in writing from the copyright owner.
+ *
+ * This software is supplied "as is" without express
+ * or implied warranty.
+ *
+ * djh@munnari.OZ.AU
+ *
+ * Supports:
+ * Linux SOCK_PACKET
+ *
+ * $Author: atp $
+ * $Revision: 1.1.1.1 $
+ *
+ *
+ * Modified for use with the linux-mopd port by Karl Maftoum
+ * u963870@student.canberra.edu.au
+ *
+ */
+
+/*
+ * include header files
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <sys/errno.h>
+#include <linux/if_ether.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <string.h>
+
+#define MOPDEF_SUPRESS_EXTERN
+#include "mopdef.h"
+
+/*
+ * definitions
+ *
+ */
+
+#define READBUFSIZ 4096
+#define NUMRDS 32
+
+struct RDS {
+ u_short dataLen;
+ u_char *dataPtr;
+};
+
+/*
+ * variables
+ *
+ */
+
+struct socklist {
+ int iflen;
+ struct sockaddr sa;
+} socklist[32];
+
+struct ifreq ifr;
+extern int errno;
+extern int promisc;
+
+struct RDS RDS[NUMRDS];
+
+/*
+ * Open and initialize packet filter
+ * for a particular protocol type.
+ *
+ */
+
+
+int
+pfInit(interface, mode, protocol, typ)
+char *interface;
+u_short protocol;
+int typ, mode;
+{
+ int s;
+ int ioarg;
+ char device[64];
+ unsigned long if_flags;
+
+
+ { u_short prot;
+
+ prot = ((typ == TRANS_8023) ? htons(ETH_P_802_2) : htons(protocol));
+ if ((s = socket(AF_INET, SOCK_PACKET, prot)) < 0) {
+ perror(interface);
+ return(-1);
+ }
+ if (s >= 32) {
+ close(s);
+ return(-1);
+ }
+ }
+
+ /*
+ * set filter for protocol and type (IPTalk, Phase 1/2)
+ *
+ */
+
+ if (setup_pf(s, protocol, typ) < 0)
+ return(-1);
+
+ /*
+ * set options, bind to underlying interface
+ *
+ */
+
+ strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
+
+ /* record socket interface name and length */
+ strncpy(socklist[s].sa.sa_data, interface, sizeof(socklist[s].sa.sa_data));
+ socklist[s].iflen = strlen(interface);
+
+ return(s);
+}
+
+/*
+ * establish protocol filter
+ *
+ */
+
+int
+setup_pf(s, prot, typ)
+int s, typ;
+u_short prot;
+{
+ int ioarg;
+ u_short offset;
+ return(0);
+}
+
+/*
+ * get the interface ethernet address
+ *
+ */
+
+int
+pfEthAddr(s, interface, addr)
+int s;
+char *interface;
+u_char *addr;
+{
+ strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) -1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)] = 0;
+ ifr.ifr_addr.sa_family = AF_INET;
+ if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+ perror("SIOCGIFHWADDR");
+ return(-1);
+ }
+ memcpy((char *)addr, ifr.ifr_hwaddr.sa_data, 6);
+ return(0);
+}
+
+/*
+ * add a multicast address to the interface
+ *
+ */
+
+int
+pfAddMulti(s, interface, addr)
+int s;
+char *interface;
+u_char *addr;
+{
+ int sock;
+
+ strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)] = 0;
+
+ ifr.ifr_addr.sa_family = AF_UNSPEC;
+ bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
+
+ /*
+ * open a socket, temporarily, to use for SIOC* ioctls
+ *
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("socket()");
+ return(-1);
+ }
+ if (ioctl(sock, SIOCADDMULTI, (caddr_t)&ifr) < 0) {
+ perror("SIOCADDMULTI");
+ close(sock);
+ return(-1);
+ }
+ close(sock);
+
+ return(0);
+}
+
+/*
+ * delete a multicast address from the interface
+ *
+ */
+
+int
+pfDelMulti(s, interface, addr)
+int s;
+char *interface;
+u_char *addr;
+{
+ int sock;
+
+ strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1);
+ ifr.ifr_name[sizeof(ifr.ifr_name)] = 0;
+
+ ifr.ifr_addr.sa_family = AF_UNSPEC;
+ bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
+
+ /*
+ * open a socket, temporarily, to use for SIOC* ioctls
+ *
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("socket()");
+ return(-1);
+ }
+ if (ioctl(sock, SIOCDELMULTI, (caddr_t)&ifr) < 0) {
+ perror("SIOCDELMULTI");
+ close(sock);
+ return(-1);
+ }
+ close(sock);
+
+ return(0);
+}
+
+/*
+ * return 1 if ethernet interface capable of multiple opens
+ *
+ */
+
+int
+eth_mopen(phase)
+int phase;
+{
+ if (phase == 2)
+ return(0);
+ return(1);
+}
+
+/*
+ * read a packet
+ * Read Data Structure describes packet(s) received
+ *
+ */
+
+
+
+
+int
+pfRead(fd, buf, len)
+int fd, len;
+u_char *buf;
+{
+ int i, cc;
+
+ int fromlen;
+ struct sockaddr sa;
+
+ RDS[0].dataLen = 0;
+ fromlen = sizeof(struct sockaddr);
+
+ if ((cc = recvfrom(fd, (char *)buf, len, 0, &sa, &fromlen)) <= 0)
+ return(cc);
+
+ /* check if from right interface */
+ for (i = socklist[fd].iflen-1; i >= 0; i--)
+ if (sa.sa_data[i] != socklist[fd].sa.sa_data[i])
+ return(0);
+
+ RDS[0].dataLen = cc;
+ RDS[0].dataPtr = buf;
+ RDS[1].dataLen = 0;
+
+ return(cc);
+}
+
+/*
+ * write a packet
+ *
+ */
+
+int
+pfWrite(fd, buf, len)
+int fd, len;
+u_char *buf;
+{
+
+ if (sendto(fd, buf, len, 0, &socklist[fd].sa, sizeof(struct sockaddr)) == len)
+ return(len);
+
+ return(-1);
+}
+
+/*
+ * Return information to device.c how to open device.
+ * In this case the driver can handle both Ethernet type II and
+ * IEEE 802.3 frames (SNAP) in a single pfOpen.
+ */
+
+int
+pfTrans(interface)
+ char *interface;
+{
+ return TRANS_ETHER+TRANS_8023;
+}
+