add chaos_calmer branch
[15.05/openwrt.git] / package / network / services / ppp / patches / 520-uniq.patch
1 --- a/pppd/plugins/rp-pppoe/common.c
2 +++ b/pppd/plugins/rp-pppoe/common.c
3 @@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char con
4      conn->session = 0;
5  
6      /* If we're using Host-Uniq, copy it over */
7 -    if (conn->useHostUniq) {
8 -       PPPoETag hostUniq;
9 -       pid_t pid = getpid();
10 -       hostUniq.type = htons(TAG_HOST_UNIQ);
11 -       hostUniq.length = htons(sizeof(pid));
12 -       memcpy(hostUniq.payload, &pid, sizeof(pid));
13 -       memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
14 -       cursor += sizeof(pid) + TAG_HDR_SIZE;
15 -       plen += sizeof(pid) + TAG_HDR_SIZE;
16 +    if (conn->hostUniq.length) {
17 +       int len = ntohs(conn->hostUniq.length);
18 +       memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
19 +       cursor += len + TAG_HDR_SIZE;
20 +       plen += len + TAG_HDR_SIZE;
21      }
22  
23      /* Copy error message */
24 --- a/pppd/plugins/rp-pppoe/discovery.c
25 +++ b/pppd/plugins/rp-pppoe/discovery.c
26 @@ -80,13 +80,10 @@ static void
27  parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
28                  void *extra)
29  {
30 -    int *val = (int *) extra;
31 -    if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
32 -       pid_t tmp;
33 -       memcpy(&tmp, data, len);
34 -       if (tmp == getpid()) {
35 -           *val = 1;
36 -       }
37 +    PPPoETag *tag = extra;
38 +
39 +    if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) {
40 +       tag->length = memcmp(data, tag->payload, len);
41      }
42  }
43  
44 @@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t
45  static int
46  packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
47  {
48 -    int forMe = 0;
49 +    PPPoETag hostUniq = conn->hostUniq;
50  
51      /* If packet is not directed to our MAC address, forget it */
52      if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
53  
54      /* If we're not using the Host-Unique tag, then accept the packet */
55 -    if (!conn->useHostUniq) return 1;
56 +    if (!conn->hostUniq.length) return 1;
57  
58 -    parsePacket(packet, parseForHostUniq, &forMe);
59 -    return forMe;
60 +    parsePacket(packet, parseForHostUniq, &hostUniq);
61 +    return (hostUniq.length == 0);
62  }
63  
64  /**********************************************************************
65 @@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn)
66      }
67  
68      /* If we're using Host-Uniq, copy it over */
69 -    if (conn->useHostUniq) {
70 -       PPPoETag hostUniq;
71 -       pid_t pid = getpid();
72 -       hostUniq.type = htons(TAG_HOST_UNIQ);
73 -       hostUniq.length = htons(sizeof(pid));
74 -       memcpy(hostUniq.payload, &pid, sizeof(pid));
75 -       CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
76 -       memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
77 -       cursor += sizeof(pid) + TAG_HDR_SIZE;
78 -       plen += sizeof(pid) + TAG_HDR_SIZE;
79 +    if (conn->hostUniq.length) {
80 +       int len = ntohs(conn->hostUniq.length);
81 +       CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
82 +       memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
83 +       cursor += len + TAG_HDR_SIZE;
84 +       plen += len + TAG_HDR_SIZE;
85      }
86  
87      /* Add our maximum MTU/MRU */
88 @@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn)
89      cursor += namelen + TAG_HDR_SIZE;
90  
91      /* If we're using Host-Uniq, copy it over */
92 -    if (conn->useHostUniq) {
93 -       PPPoETag hostUniq;
94 -       pid_t pid = getpid();
95 -       hostUniq.type = htons(TAG_HOST_UNIQ);
96 -       hostUniq.length = htons(sizeof(pid));
97 -       memcpy(hostUniq.payload, &pid, sizeof(pid));
98 -       CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
99 -       memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
100 -       cursor += sizeof(pid) + TAG_HDR_SIZE;
101 -       plen += sizeof(pid) + TAG_HDR_SIZE;
102 +    if (conn->hostUniq.length) {
103 +       int len = ntohs(conn->hostUniq.length);
104 +       CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
105 +       memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
106 +       cursor += len + TAG_HDR_SIZE;
107 +       plen += len + TAG_HDR_SIZE;
108      }
109  
110      /* Add our maximum MTU/MRU */
111 --- a/pppd/plugins/rp-pppoe/plugin.c
112 +++ b/pppd/plugins/rp-pppoe/plugin.c
113 @@ -65,6 +65,7 @@ static char *existingSession = NULL;
114  static int printACNames = 0;
115  static char *pppoe_reqd_mac = NULL;
116  unsigned char pppoe_reqd_mac_addr[6];
117 +static char *host_uniq = NULL;
118  
119  static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
120  static option_t Options[] = {
121 @@ -82,6 +83,8 @@ static option_t Options[] = {
122        "Be verbose about discovered access concentrators"},
123      { "pppoe-mac", o_string, &pppoe_reqd_mac,
124        "Only connect to specified MAC address" },
125 +    { "host-uniq", o_string, &host_uniq,
126 +      "Specify custom Host-Uniq" },
127      { NULL }
128  };
129  int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
130 @@ -107,7 +110,6 @@ PPPOEInitDevice(void)
131      conn->ifName = devnam;
132      conn->discoverySocket = -1;
133      conn->sessionSocket = -1;
134 -    conn->useHostUniq = 1;
135      conn->printACNames = printACNames;
136      conn->discoveryTimeout = PADI_TIMEOUT;
137      return 1;
138 @@ -163,6 +165,9 @@ PPPOEConnectDevice(void)
139      if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
140         lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
141  
142 +    if (host_uniq && !parseHostUniq(host_uniq, &conn->hostUniq))
143 +       fatal("Illegal value for host-uniq option");
144 +
145      conn->acName = acName;
146      conn->serviceName = pppd_pppoe_service;
147      strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
148 --- a/pppd/plugins/rp-pppoe/pppoe-discovery.c
149 +++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c
150 @@ -344,7 +344,7 @@ packetIsForMe(PPPoEConnection *conn, PPP
151      if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
152  
153      /* If we're not using the Host-Unique tag, then accept the packet */
154 -    if (!conn->useHostUniq) return 1;
155 +    if (!conn->hostUniq.length) return 1;
156  
157      parsePacket(packet, parseForHostUniq, &forMe);
158      return forMe;
159 @@ -470,16 +470,12 @@ sendPADI(PPPoEConnection *conn)
160      cursor += namelen + TAG_HDR_SIZE;
161  
162      /* If we're using Host-Uniq, copy it over */
163 -    if (conn->useHostUniq) {
164 -       PPPoETag hostUniq;
165 -       pid_t pid = getpid();
166 -       hostUniq.type = htons(TAG_HOST_UNIQ);
167 -       hostUniq.length = htons(sizeof(pid));
168 -       memcpy(hostUniq.payload, &pid, sizeof(pid));
169 -       CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
170 -       memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
171 -       cursor += sizeof(pid) + TAG_HDR_SIZE;
172 -       plen += sizeof(pid) + TAG_HDR_SIZE;
173 +    if (conn->hostUniq.length) {
174 +       int len = ntohs(conn->hostUniq.length);
175 +       CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
176 +       memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
177 +       cursor += len + TAG_HDR_SIZE;
178 +       plen += len + TAG_HDR_SIZE;
179      }
180  
181      packet.length = htons(plen);
182 @@ -641,7 +637,7 @@ int main(int argc, char *argv[])
183  
184      memset(conn, 0, sizeof(PPPoEConnection));
185  
186 -    while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) {
187 +    while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) {
188         switch(opt) {
189         case 'S':
190             conn->serviceName = xstrdup(optarg);
191 @@ -650,7 +646,23 @@ int main(int argc, char *argv[])
192             conn->acName = xstrdup(optarg);
193             break;
194         case 'U':
195 -           conn->useHostUniq = 1;
196 +           if(conn->hostUniq.length) {
197 +               fprintf(stderr, "-U and -W are mutually exclusive\n");
198 +               exit(EXIT_FAILURE);
199 +           }
200 +            char pidbuf[5];
201 +            snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid());
202 +            parseHostUniq(pidbuf, &conn->hostUniq);
203 +           break;
204 +       case 'W':
205 +           if(conn->hostUniq.length) {
206 +               fprintf(stderr, "-U and -W are mutually exclusive\n");
207 +               exit(EXIT_FAILURE);
208 +           }
209 +           if (!parseHostUniq(optarg, &conn->hostUniq)) {
210 +                fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
211 +                exit(EXIT_FAILURE);
212 +            }
213             break;
214         case 'D':
215             conn->debugFile = fopen(optarg, "w");
216 --- a/pppd/plugins/rp-pppoe/pppoe.h
217 +++ b/pppd/plugins/rp-pppoe/pppoe.h
218 @@ -21,6 +21,8 @@
219  
220  #include <stdio.h>             /* For FILE */
221  #include <sys/types.h>         /* For pid_t */
222 +#include <ctype.h>
223 +#include <string.h>
224  
225  /* How do we access raw Ethernet devices? */
226  #undef USE_LINUX_PACKET
227 @@ -224,7 +226,7 @@ typedef struct PPPoEConnectionStruct {
228      char *serviceName;         /* Desired service name, if any */
229      char *acName;              /* Desired AC name, if any */
230      int synchronous;           /* Use synchronous PPP */
231 -    int useHostUniq;           /* Use Host-Uniq tag */
232 +    PPPoETag hostUniq;         /* Use Host-Uniq tag */
233      int printACNames;          /* Just print AC names */
234      FILE *debugFile;           /* Debug file for dumping packets */
235      int numPADOs;              /* Number of PADO packets received */
236 @@ -280,6 +282,33 @@ void pppoe_printpkt(PPPoEPacket *packet,
237                     void (*printer)(void *, char *, ...), void *arg);
238  void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
239  
240 +static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
241 +{
242 +    int i, len = strlen(uniq);
243 +
244 +#define hex(x) \
245 +    (((x) <= '9') ? ((x) - '0') : \
246 +        (((x) <= 'F') ? ((x) - 'A' + 10) : \
247 +            ((x) - 'a' + 10)))
248 +
249 +    if (len % 2)
250 +        return 0;
251 +
252 +    for (i = 0; i < len; i += 2)
253 +    {
254 +        if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
255 +            return 0;
256 +
257 +        tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1]));
258 +    }
259 +
260 +#undef hex
261 +
262 +    tag->type = htons(TAG_HOST_UNIQ);
263 +    tag->length = htons(len / 2);
264 +    return 1;
265 +}
266 +
267  #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
268  
269  #define CHECK_ROOM(cursor, start, len) \