Skip to content

Commit

Permalink
pppoe-server: -n to use vendor specific tag as remote*N*umber.
Browse files Browse the repository at this point in the history
RFC 2516 discourages it's use but it looks like at least some switches
adds a port-configured circuit-id throught this.  This does not seem to
be well defined but at least CISCO and the S3900 series switches from
fs.com has stuff about this in the documentation, which leads me to
believe it's common practise.

Signed-off-by: Jaco Kroon <[email protected]>
  • Loading branch information
jkroonza committed Nov 7, 2024
1 parent 7390e76 commit a0cb5c7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
36 changes: 30 additions & 6 deletions src/pppoe-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ int NumInterfaces = 0;
int MaxInterfaces = 0;
int draining = 0;

int vendorTagAsRemoteNumber = 0;

/* The number of session slots */
size_t NumSessionSlots;

Expand Down Expand Up @@ -176,6 +178,7 @@ static PPPoETag hostUniq;
static PPPoETag relayId;
static PPPoETag receivedCookie;
static PPPoETag requestedService;
static PPPoETag vendorTag;

#define HOSTNAMELEN 256

Expand Down Expand Up @@ -514,6 +517,11 @@ parsePADRTags(uint16_t type, uint16_t len, unsigned char *data,
requestedService.length = htons(len);
memcpy(requestedService.payload, data, len);
break;
case TAG_VENDOR_SPECIFIC:
vendorTag.type = htons(type);
vendorTag.length = htons(len);
memcpy(vendorTag.payload, data, len);
break;
}
}

Expand Down Expand Up @@ -881,6 +889,7 @@ processPADR(Interface *ethif, PPPoEPacket *packet, int len)
hostUniq.type = 0;
receivedCookie.type = 0;
requestedService.type = 0;
vendorTag.type = 0;

/* Ignore PADR's not directed at us */
if (memcmp(packet->ethHdr.h_dest, myAddr, ETH_ALEN)) return;
Expand Down Expand Up @@ -979,6 +988,7 @@ processPADR(Interface *ethif, PPPoEPacket *packet, int len)
cliSession->funcs = &DefaultSessionFunctionTable;
cliSession->startTime = time(NULL);
cliSession->serviceName = serviceName;
cliSession->remoteNumber = NULL;

/* Create child process, send PADS packet back */
child = fork();
Expand Down Expand Up @@ -1071,6 +1081,10 @@ processPADR(Interface *ethif, PPPoEPacket *packet, int len)
cursor += ntohs(hostUniq.length) + TAG_HDR_SIZE;
plen += ntohs(hostUniq.length) + TAG_HDR_SIZE;
}
if (vendorTag.type && ntohs(vendorTag.length) > TAG_HDR_SIZE && vendorTagAsRemoteNumber) {
vendorTag.payload[ntohs(vendorTag.length)] = 0; /* Make sure it's NUL terminated */
cliSession->remoteNumber = (char*)vendorTag.payload + TAG_HDR_SIZE;
}
pads.length = htons(plen);
sendPacket(NULL, sock, &pads, (int) (plen + HDR_SIZE));

Expand Down Expand Up @@ -1209,7 +1223,7 @@ main(int argc, char **argv)
char const *s;
int cookie_ok = 0;

char const *options = "X:ix:hI:C:L:R:T:m:FN:f:O:o:skp:lrudPS:q:Q:H:M:U:g:";
char const *options = "X:ix:hI:C:L:R:T:m:FN:f:O:o:skp:lrudPS:q:Q:H:M:U:g:n";

if (getuid() != geteuid() ||
getgid() != getegid()) {
Expand Down Expand Up @@ -1457,6 +1471,10 @@ main(int argc, char **argv)
SET_STRING(unix_control, optarg);
break;

case 'n':
vendorTagAsRemoteNumber = 1;
break;

case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
Expand Down Expand Up @@ -1989,11 +2007,17 @@ startPPPD(ClientSession *session)
argv[c++] = "default-asyncmap";

argv[c++] = "remotenumber";
snprintf(buffer, SMALLBUF, "%02x:%02x:%02x:%02x:%02x:%02x",
session->eth[0], session->eth[1], session->eth[2],
session->eth[3], session->eth[4], session->eth[5]);
if (!(argv[c++] = strdup(buffer))) {
exit(EXIT_FAILURE);
if (session->remoteNumber) {
if (!(argv[c++] = strdup(session->remoteNumber))) {
exit(EXIT_FAILURE);
}
} else {
snprintf(buffer, SMALLBUF, "%02x:%02x:%02x:%02x:%02x:%02x",
session->eth[0], session->eth[1], session->eth[2],
session->eth[3], session->eth[4], session->eth[5]);
if (!(argv[c++] = strdup(buffer))) {
exit(EXIT_FAILURE);
}
}

if (PassUnitOptionToPPPD) {
Expand Down
1 change: 1 addition & 0 deletions src/pppoe-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct ClientSessionStruct {
time_t startTime; /* When session started */
char const *serviceName; /* Service name */
uint16_t requested_mtu; /* Requested PPP_MAX_PAYLOAD per RFC 4638 */
char *remoteNumber; /* Vendor-Specific tag extracted remote number ... this is a bit of a hack */
} ClientSession;

/* Hack for daemonizing */
Expand Down

0 comments on commit a0cb5c7

Please sign in to comment.