Skip to content

Instantly share code, notes, and snippets.

@Robertof
Created January 4, 2016 16:09
Show Gist options
  • Save Robertof/93d5929ad30030024c29 to your computer and use it in GitHub Desktop.
Save Robertof/93d5929ad30030024c29 to your computer and use it in GitHub Desktop.
A patch for pppoe-relay which completely removes the usage of the tag "Relay-Session-Id". The tag, used to keep track of the clients making use of the PPPoEd protocol, has been replaced with two variables inside the source code. This allows this instance of pppoe-relay to work with other instances of pppoe-relay which do not have the same patch …
--- relay.orig 2016-01-04 17:02:33.538674500 +0100
+++ relay.c 2016-01-04 03:18:44.972518900 +0100
@@ -83,6 +83,31 @@
/* Hack for daemonizing */
#define CLOSEFD 64
+/* Debug flag */
+//#define ROB_DEBUG
+
+/* No syslog when debugging! */
+#ifdef ROB_DEBUG
+# define syslog(_, fmt, args...) printf(fmt "\n", args)
+#endif
+
+/* Data used to replace Relay-Session-Id completely */
+unsigned char currentAddress[ETH_ALEN];
+int currentIfIndex = -1;
+
+#ifdef ROB_DEBUG
+void printMacAddress(char *denomination, unsigned char *address) {
+ printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ denomination,
+ currentAddress[0],
+ currentAddress[1],
+ currentAddress[2],
+ currentAddress[3],
+ currentAddress[4],
+ currentAddress[5]);
+}
+#endif
+
/**********************************************************************
*%FUNCTION: keepDescriptor
*%ARGUMENTS:
@@ -991,11 +1016,12 @@
PPPoEPacket *packet,
int size)
{
+#if 0
PPPoETag tag;
unsigned char *loc;
- int i, r;
-
- int ifIndex;
+ int r, ifIndex;
+#endif
+ int i;
/* Can a client legally be behind this interface? */
if (!iface->clientOK) {
@@ -1039,26 +1065,31 @@
return;
}
- /* Get array index of interface */
- ifIndex = iface - Interfaces;
-
+#if 0
loc = findTag(packet, TAG_RELAY_SESSION_ID, &tag);
if (!loc) {
tag.type = htons(TAG_RELAY_SESSION_ID);
tag.length = htons(MY_RELAY_TAG_LEN);
memcpy(tag.payload, &ifIndex, sizeof(ifIndex));
memcpy(tag.payload+sizeof(ifIndex), packet->ethHdr.h_source, ETH_ALEN);
- /* Add a relay tag if there's room */
+ // Add a relay tag if there's room
r = addTag(packet, &tag);
if (r < 0) return;
size += r;
} else {
- /* We do not re-use relay-id tags. Drop the frame. The RFC says the
- relay agent SHOULD return a Generic-Error tag, but this does not
- make sense for PADI packets. */
+ // We do not re-use relay-id tags. Drop the frame. The RFC says the
+ // relay agent SHOULD return a Generic-Error tag, but this does not
+ // make sense for PADI packets.
return;
}
-
+#endif
+ // Save the source MAC address and the ifIndex for later
+ currentIfIndex = iface - Interfaces;
+ memcpy(currentAddress, packet->ethHdr.h_source, ETH_ALEN);
+#ifdef ROB_DEBUG
+ printMacAddress("PADI packet: currentAddress (src)", currentAddress);
+ printf("PADI packet: currentIf (src): %s\n", Interfaces[currentIfIndex].name);
+#endif
/* Broadcast the PADI on all AC-capable interfaces except the interface
on which it came */
for (i=0; i < NumInterfaces; i++) {
@@ -1085,10 +1116,13 @@
PPPoEPacket *packet,
int size)
{
+#if 0
PPPoETag tag;
unsigned char *loc;
- int ifIndex;
int acIndex;
+ int ifIndex;
+#endif
+ PPPoEInterface *outIface;
/* Can a server legally be behind this interface? */
if (!iface->acOK) {
@@ -1104,8 +1138,6 @@
return;
}
- acIndex = iface - Interfaces;
-
/* Source address must be unicast */
if (BROADCAST(packet->ethHdr.h_source)) {
syslog(LOG_ERR,
@@ -1125,6 +1157,7 @@
return;
}
+#if 0
/* Find relay tag */
loc = findTag(packet, TAG_RELAY_SESSION_ID, &tag);
if (!loc) {
@@ -1175,15 +1208,29 @@
/* Replace Relay-ID tag with opposite-direction tag */
memcpy(loc+TAG_HDR_SIZE, &acIndex, sizeof(acIndex));
memcpy(loc+TAG_HDR_SIZE+sizeof(ifIndex), packet->ethHdr.h_source, ETH_ALEN);
+#endif
+
+ if (currentIfIndex == -1)
+ return;
+
+#ifdef ROB_DEBUG
+ printMacAddress("PADO packet: currentAddress (dest)", currentAddress);
+ printf("PADO packet: currentIf (dest): %s\n", Interfaces[currentIfIndex].name);
+#endif
/* Set destination address to MAC address in relay ID */
- memcpy(packet->ethHdr.h_dest, tag.payload + sizeof(ifIndex), ETH_ALEN);
+ memcpy(packet->ethHdr.h_dest, currentAddress, ETH_ALEN);
+
+ /* Update currentAddress and currentIfIndex */
+ outIface = &Interfaces[currentIfIndex];
+ memcpy(currentAddress, packet->ethHdr.h_source, ETH_ALEN);
+ currentIfIndex = iface - Interfaces;
/* Set source address to MAC address of interface */
- memcpy(packet->ethHdr.h_source, Interfaces[ifIndex].mac, ETH_ALEN);
+ memcpy(packet->ethHdr.h_source, outIface->mac, ETH_ALEN);
/* Send the PADO to the proper client */
- sendPacket(NULL, Interfaces[ifIndex].discoverySock, packet, size);
+ sendPacket(NULL, outIface->discoverySock, packet, size);
}
/**********************************************************************
@@ -1201,10 +1248,12 @@
PPPoEPacket *packet,
int size)
{
+#if 0
PPPoETag tag;
unsigned char *loc;
- int ifIndex;
- int cliIndex;
+ int ifIndex, cliIndex;
+#endif
+ PPPoEInterface *outIface;
/* Can a client legally be behind this interface? */
if (!iface->clientOK) {
@@ -1220,8 +1269,6 @@
return;
}
- cliIndex = iface - Interfaces;
-
/* Source address must be unicast */
if (NOT_UNICAST(packet->ethHdr.h_source)) {
syslog(LOG_ERR,
@@ -1241,6 +1288,7 @@
return;
}
+#if 0
/* Find relay tag */
loc = findTag(packet, TAG_RELAY_SESSION_ID, &tag);
if (!loc) {
@@ -1291,15 +1339,29 @@
/* Replace Relay-ID tag with opposite-direction tag */
memcpy(loc+TAG_HDR_SIZE, &cliIndex, sizeof(cliIndex));
memcpy(loc+TAG_HDR_SIZE+sizeof(ifIndex), packet->ethHdr.h_source, ETH_ALEN);
+#endif
+
+ if (currentIfIndex == -1)
+ return;
+
+#ifdef ROB_DEBUG
+ printMacAddress("PADR packet: currentAddress (dest)", currentAddress);
+ printf("PADR packet: currentIf (dest): %s\n", Interfaces[currentIfIndex].name);
+#endif
/* Set destination address to MAC address in relay ID */
- memcpy(packet->ethHdr.h_dest, tag.payload + sizeof(ifIndex), ETH_ALEN);
+ memcpy(packet->ethHdr.h_dest, currentAddress, ETH_ALEN);
+
+ /* Update currentAddress and currentIfIndex */
+ outIface = &Interfaces[currentIfIndex];
+ memcpy(currentAddress, packet->ethHdr.h_source, ETH_ALEN);
+ currentIfIndex = iface - Interfaces;
/* Set source address to MAC address of interface */
- memcpy(packet->ethHdr.h_source, Interfaces[ifIndex].mac, ETH_ALEN);
+ memcpy(packet->ethHdr.h_source, outIface->mac, ETH_ALEN);
/* Send the PADR to the proper access concentrator */
- sendPacket(NULL, Interfaces[ifIndex].discoverySock, packet, size);
+ sendPacket(NULL, outIface->discoverySock, packet, size);
}
/**********************************************************************
@@ -1317,9 +1379,11 @@
PPPoEPacket *packet,
int size)
{
+#if 0
PPPoETag tag;
unsigned char *loc;
int ifIndex;
+#endif
PPPoESession *ses = NULL;
SessionHash *sh;
@@ -1356,6 +1420,7 @@
return;
}
+#if 0
/* Find relay tag */
loc = findTag(packet, TAG_RELAY_SESSION_ID, &tag);
if (!loc) {
@@ -1402,7 +1467,13 @@
iface->name);
return;
}
-
+#endif
+ if (currentIfIndex == -1)
+ return;
+#ifdef ROB_DEBUG
+ printMacAddress("PADS packet: currentAddress (dest)", currentAddress);
+ printf("PADS packet: currentIf (dest): %s\n", Interfaces[currentIfIndex].name);
+#endif
/* If session ID is zero, it's the AC respoding with an error.
Just relay it; do not create a session */
if (packet->session != htons(0)) {
@@ -1418,9 +1489,9 @@
if (!ses) {
/* Create a new session */
- ses = createSession(iface, &Interfaces[ifIndex],
+ ses = createSession(iface, &Interfaces[currentIfIndex],
packet->ethHdr.h_source,
- loc + TAG_HDR_SIZE + sizeof(ifIndex), packet->session);
+ currentAddress, packet->session);
if (!ses) {
/* Can't allocate session -- send error PADS to client and
PADT to server */
@@ -1430,8 +1501,8 @@
} else {
hu = NULL;
}
- relaySendError(CODE_PADS, htons(0), &Interfaces[ifIndex],
- loc + TAG_HDR_SIZE + sizeof(ifIndex),
+ relaySendError(CODE_PADS, htons(0), &Interfaces[currentIfIndex],
+ currentAddress,
hu, "RP-PPPoE: Relay: Unable to allocate session");
relaySendError(CODE_PADT, packet->session, iface,
packet->ethHdr.h_source, NULL,
@@ -1443,18 +1514,21 @@
packet->session = ses->sesNum;
}
+#if 0
/* Remove relay-ID tag */
removeBytes(packet, loc, MY_RELAY_TAG_LEN + TAG_HDR_SIZE);
size -= (MY_RELAY_TAG_LEN + TAG_HDR_SIZE);
+#endif
/* Set destination address to MAC address in relay ID */
- memcpy(packet->ethHdr.h_dest, tag.payload + sizeof(ifIndex), ETH_ALEN);
+ memcpy(packet->ethHdr.h_dest, currentAddress, ETH_ALEN);
/* Set source address to MAC address of interface */
- memcpy(packet->ethHdr.h_source, Interfaces[ifIndex].mac, ETH_ALEN);
+ memcpy(packet->ethHdr.h_source, Interfaces[currentIfIndex].mac, ETH_ALEN);
/* Send the PADS to the proper client */
- sendPacket(NULL, Interfaces[ifIndex].discoverySock, packet, size);
+ sendPacket(NULL, Interfaces[currentIfIndex].discoverySock, packet, size);
+ currentIfIndex = -1; // reset
}
/**********************************************************************
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment