mirror of https://gitee.com/openkylin/ppp.git
[PATCH] pppoe: custom host-uniq tag
Add pppoe 'host-uniq' option to set an arbitrary host-uniq tag instead of the pppd pid. Some ISPs use such tag to authenticate the CPE, so it must be set to a proper value to connect. Signed-off-by: Matteo Croce <matteo@openwrt.org> Signed-off-by: Jo-Philipp Wich <jow@openwrt.org> Gbp-Pq: Name pr-28-pppoe-custom-host-uniq-tag.patch
This commit is contained in:
parent
f39727fffe
commit
f569843120
|
@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char const *msg)
|
|||
conn->session = 0;
|
||||
|
||||
/* If we're using Host-Uniq, copy it over */
|
||||
if (conn->useHostUniq) {
|
||||
PPPoETag hostUniq;
|
||||
pid_t pid = getpid();
|
||||
hostUniq.type = htons(TAG_HOST_UNIQ);
|
||||
hostUniq.length = htons(sizeof(pid));
|
||||
memcpy(hostUniq.payload, &pid, sizeof(pid));
|
||||
memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
|
||||
cursor += sizeof(pid) + TAG_HDR_SIZE;
|
||||
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||||
if (conn->hostUniq.length) {
|
||||
int len = ntohs(conn->hostUniq.length);
|
||||
memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
|
||||
cursor += len + TAG_HDR_SIZE;
|
||||
plen += len + TAG_HDR_SIZE;
|
||||
}
|
||||
|
||||
/* Copy error message */
|
||||
|
|
|
@ -80,13 +80,10 @@ static void
|
|||
parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
|
||||
void *extra)
|
||||
{
|
||||
int *val = (int *) extra;
|
||||
if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
|
||||
pid_t tmp;
|
||||
memcpy(&tmp, data, len);
|
||||
if (tmp == getpid()) {
|
||||
*val = 1;
|
||||
}
|
||||
PPPoETag *tag = extra;
|
||||
|
||||
if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) {
|
||||
tag->length = memcmp(data, tag->payload, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
|
|||
static int
|
||||
packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
|
||||
{
|
||||
int forMe = 0;
|
||||
PPPoETag hostUniq = conn->hostUniq;
|
||||
|
||||
/* If packet is not directed to our MAC address, forget it */
|
||||
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
|
||||
|
||||
/* If we're not using the Host-Unique tag, then accept the packet */
|
||||
if (!conn->useHostUniq) return 1;
|
||||
if (!conn->hostUniq.length) return 1;
|
||||
|
||||
parsePacket(packet, parseForHostUniq, &forMe);
|
||||
return forMe;
|
||||
parsePacket(packet, parseForHostUniq, &hostUniq);
|
||||
return !hostUniq.length;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn)
|
|||
}
|
||||
|
||||
/* If we're using Host-Uniq, copy it over */
|
||||
if (conn->useHostUniq) {
|
||||
PPPoETag hostUniq;
|
||||
pid_t pid = getpid();
|
||||
hostUniq.type = htons(TAG_HOST_UNIQ);
|
||||
hostUniq.length = htons(sizeof(pid));
|
||||
memcpy(hostUniq.payload, &pid, sizeof(pid));
|
||||
CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
|
||||
memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
|
||||
cursor += sizeof(pid) + TAG_HDR_SIZE;
|
||||
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||||
if (conn->hostUniq.length) {
|
||||
int len = ntohs(conn->hostUniq.length);
|
||||
CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
|
||||
memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
|
||||
cursor += len + TAG_HDR_SIZE;
|
||||
plen += len + TAG_HDR_SIZE;
|
||||
}
|
||||
|
||||
/* Add our maximum MTU/MRU */
|
||||
|
@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn)
|
|||
cursor += namelen + TAG_HDR_SIZE;
|
||||
|
||||
/* If we're using Host-Uniq, copy it over */
|
||||
if (conn->useHostUniq) {
|
||||
PPPoETag hostUniq;
|
||||
pid_t pid = getpid();
|
||||
hostUniq.type = htons(TAG_HOST_UNIQ);
|
||||
hostUniq.length = htons(sizeof(pid));
|
||||
memcpy(hostUniq.payload, &pid, sizeof(pid));
|
||||
CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
|
||||
memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
|
||||
cursor += sizeof(pid) + TAG_HDR_SIZE;
|
||||
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||||
if (conn->hostUniq.length) {
|
||||
int len = ntohs(conn->hostUniq.length);
|
||||
CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
|
||||
memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
|
||||
cursor += len + TAG_HDR_SIZE;
|
||||
plen += len + TAG_HDR_SIZE;
|
||||
}
|
||||
|
||||
/* Add our maximum MTU/MRU */
|
||||
|
|
|
@ -68,6 +68,7 @@ static char *existingSession = NULL;
|
|||
static int printACNames = 0;
|
||||
static char *pppoe_reqd_mac = NULL;
|
||||
unsigned char pppoe_reqd_mac_addr[6];
|
||||
static char *host_uniq = NULL;
|
||||
|
||||
static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
|
||||
static option_t Options[] = {
|
||||
|
@ -85,6 +86,8 @@ static option_t Options[] = {
|
|||
"Be verbose about discovered access concentrators"},
|
||||
{ "pppoe-mac", o_string, &pppoe_reqd_mac,
|
||||
"Only connect to specified MAC address" },
|
||||
{ "host-uniq", o_string, &host_uniq,
|
||||
"Specify custom Host-Uniq" },
|
||||
{ NULL }
|
||||
};
|
||||
int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
|
||||
|
@ -110,7 +113,6 @@ PPPOEInitDevice(void)
|
|||
conn->ifName = devnam;
|
||||
conn->discoverySocket = -1;
|
||||
conn->sessionSocket = -1;
|
||||
conn->useHostUniq = 1;
|
||||
conn->printACNames = printACNames;
|
||||
conn->discoveryTimeout = PADI_TIMEOUT;
|
||||
return 1;
|
||||
|
@ -166,6 +168,9 @@ PPPOEConnectDevice(void)
|
|||
if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
|
||||
lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
|
||||
|
||||
if (host_uniq && !parseHostUniq(host_uniq, &conn->hostUniq))
|
||||
fatal("Illegal value for host-uniq option");
|
||||
|
||||
conn->acName = acName;
|
||||
conn->serviceName = pppd_pppoe_service;
|
||||
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
|
||||
|
|
|
@ -356,7 +356,7 @@ packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
|
|||
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
|
||||
|
||||
/* If we're not using the Host-Unique tag, then accept the packet */
|
||||
if (!conn->useHostUniq) return 1;
|
||||
if (!conn->hostUniq.length) return 1;
|
||||
|
||||
parsePacket(packet, parseForHostUniq, &forMe);
|
||||
return forMe;
|
||||
|
@ -482,16 +482,12 @@ sendPADI(PPPoEConnection *conn)
|
|||
cursor += namelen + TAG_HDR_SIZE;
|
||||
|
||||
/* If we're using Host-Uniq, copy it over */
|
||||
if (conn->useHostUniq) {
|
||||
PPPoETag hostUniq;
|
||||
pid_t pid = getpid();
|
||||
hostUniq.type = htons(TAG_HOST_UNIQ);
|
||||
hostUniq.length = htons(sizeof(pid));
|
||||
memcpy(hostUniq.payload, &pid, sizeof(pid));
|
||||
CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
|
||||
memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
|
||||
cursor += sizeof(pid) + TAG_HDR_SIZE;
|
||||
plen += sizeof(pid) + TAG_HDR_SIZE;
|
||||
if (conn->hostUniq.length) {
|
||||
int len = ntohs(conn->hostUniq.length);
|
||||
CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
|
||||
memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
|
||||
cursor += len + TAG_HDR_SIZE;
|
||||
plen += len + TAG_HDR_SIZE;
|
||||
}
|
||||
|
||||
packet.length = htons(plen);
|
||||
|
@ -653,7 +649,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
memset(conn, 0, sizeof(PPPoEConnection));
|
||||
|
||||
while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
|
||||
while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) {
|
||||
switch(opt) {
|
||||
case 'S':
|
||||
conn->serviceName = xstrdup(optarg);
|
||||
|
@ -662,7 +658,23 @@ int main(int argc, char *argv[])
|
|||
conn->acName = xstrdup(optarg);
|
||||
break;
|
||||
case 'U':
|
||||
conn->useHostUniq = 1;
|
||||
if(conn->hostUniq.length) {
|
||||
fprintf(stderr, "-U and -W are mutually exclusive\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
char pidbuf[5];
|
||||
snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid());
|
||||
parseHostUniq(pidbuf, &conn->hostUniq);
|
||||
break;
|
||||
case 'W':
|
||||
if(conn->hostUniq.length) {
|
||||
fprintf(stderr, "-U and -W are mutually exclusive\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!parseHostUniq(optarg, &conn->hostUniq)) {
|
||||
fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
conn->debugFile = fopen(optarg, "w");
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <stdio.h> /* For FILE */
|
||||
#include <sys/types.h> /* For pid_t */
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/* How do we access raw Ethernet devices? */
|
||||
#undef USE_LINUX_PACKET
|
||||
|
@ -236,7 +238,7 @@ typedef struct PPPoEConnectionStruct {
|
|||
char *serviceName; /* Desired service name, if any */
|
||||
char *acName; /* Desired AC name, if any */
|
||||
int synchronous; /* Use synchronous PPP */
|
||||
int useHostUniq; /* Use Host-Uniq tag */
|
||||
PPPoETag hostUniq; /* Use Host-Uniq tag */
|
||||
int printACNames; /* Just print AC names */
|
||||
FILE *debugFile; /* Debug file for dumping packets */
|
||||
int numPADOs; /* Number of PADO packets received */
|
||||
|
@ -292,6 +294,33 @@ void pppoe_printpkt(PPPoEPacket *packet,
|
|||
void (*printer)(void *, char *, ...), void *arg);
|
||||
void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
|
||||
|
||||
static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
|
||||
{
|
||||
int i, len = strlen(uniq);
|
||||
|
||||
#define hex(x) \
|
||||
(((x) <= '9') ? ((x) - '0') : \
|
||||
(((x) <= 'F') ? ((x) - 'A' + 10) : \
|
||||
((x) - 'a' + 10)))
|
||||
|
||||
if (len % 2)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
|
||||
return 0;
|
||||
|
||||
tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1]));
|
||||
}
|
||||
|
||||
#undef hex
|
||||
|
||||
tag->type = htons(TAG_HOST_UNIQ);
|
||||
tag->length = htons(len / 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
|
||||
|
||||
#define CHECK_ROOM(cursor, start, len) \
|
||||
|
|
Loading…
Reference in New Issue