32#if PPP_SUPPORT && defined(HAVE_MULTILINK)
49#include <netinet/in.h>
56#include "netif/ppp/tdb.h"
58bool endpoint_specified;
64extern TDB_CONTEXT *pppdb;
67static void make_bundle_links (
int append);
68static void remove_bundle_link (
void);
69static void iterate_bundle_links (
void (*
func) (
char *));
71static int get_default_epdisc (
struct epdisc *);
72static int parse_num (
char *
str,
const char *
key,
int *valp);
73static int owns_unit (TDB_DATA
pid,
int unit);
75#define set_ip_epdisc(ep, addr) do { \
77 ep->value[0] = addr >> 24; \
78 ep->value[1] = addr >> 16; \
79 ep->value[2] = addr >> 8; \
80 ep->value[3] = addr; \
83#define LOCAL_IP_ADDR(addr) \
84 (((addr) & 0xff000000) == 0x0a000000 \
85 || ((addr) & 0xfff00000) == 0xac100000 \
86 || ((addr) & 0xffff0000) == 0xc0a80000)
88#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH)
93 lcp_options *wo = &lcp_wantoptions[0];
94 lcp_options *ao = &lcp_allowoptions[0];
108 if (!wo->neg_endpoint && !noendpoint) {
110 wo->neg_endpoint = get_default_epdisc(&wo->endpoint);
121 lcp_options *go = &lcp_gotoptions[0];
122 lcp_options *ho = &lcp_hisoptions[0];
123 lcp_options *ao = &lcp_allowoptions[0];
129 if (doing_multilink) {
131 if (!go->neg_mrru || !ho->neg_mrru) {
132 notice(
"oops, didn't get multilink on renegotiation");
133 lcp_close(pcb,
"multilink required");
141 if (!go->neg_mrru || !ho->neg_mrru) {
144 notice(
"oops, multilink negotiated only for receive");
145 mtu = ho->neg_mru? ho->mru: PPP_DEFMRU;
150 cfg_bundle(0, 0, 0, 0);
151 ppp_netif_set_mtu(pcb, mtu);
154 make_new_bundle(0, 0, 0, 0);
156 ppp_netif_set_mtu(pcb, mtu);
168 l = 4 *
strlen(peer_authname) + 10;
169 if (ho->neg_endpoint)
170 l += 3 * ho->endpoint.length + 8;
172 l += 3 *
strlen(bundle_name) + 2;
175 novm(
"bundle identifier");
178 p += slprintf(
p,
l-1,
"BUNDLE=\"%q\"", peer_authname);
179 if (ho->neg_endpoint || bundle_name)
181 if (ho->neg_endpoint)
182 p += slprintf(
p, bundle_id+
l-
p,
"%s",
183 epdisc_to_str(&ho->endpoint));
185 p += slprintf(
p, bundle_id+
l-
p,
"/%v", bundle_name);
190 if (blinks_id ==
NULL)
191 novm(
"bundle links key");
192 slprintf(blinks_id,
l + 7,
"BUNDLE_LINKS=%s", bundle_id + 7);
200 cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
201 ppp_netif_set_mtu(pcb, mtu);
202 script_setenv(
"BUNDLE", bundle_id + 7, 1);
211 key.dptr = bundle_id;
212 key.dsize =
p - bundle_id;
213 pid = tdb_fetch(pppdb,
key);
216 rec = tdb_fetch(pppdb,
pid);
217 if (rec.dptr !=
NULL && rec.dsize > 0) {
219 rec.dptr[rec.dsize-1] = 0;
221 parse_num(rec.dptr,
"IFNAME=ppp", &
unit);
223 if (!parse_num(rec.dptr,
"PPPD_PID=", &pppd_pid)
224 || !process_exists(pppd_pid)
234 if (bundle_attach(
unit)) {
236 script_setenv(
"BUNDLE", bundle_id + 7, 0);
237 make_bundle_links(1);
239 info(
"Link attached to %s", ifname);
246 make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf);
248 ppp_netif_set_mtu(pcb, mtu);
249 script_setenv(
"BUNDLE", bundle_id + 7, 1);
250 make_bundle_links(pcb);
252 info(
"New bundle %s created", ifname);
253 multilink_master = 1;
260 remove_bundle_link();
264static void sendhup(
char *
str)
270 dbglog(
"sending SIGHUP to process %d",
pid);
275void mp_bundle_terminated()
279 bundle_terminating = 1;
280 upper_layers_down(pcb);
281 notice(
"Connection terminated.");
287 script_unsetenv(
"IFNAME");
292 iterate_bundle_links(sendhup);
293 key.dptr = blinks_id;
295 tdb_delete(pppdb,
key);
298 new_phase(PPP_PHASE_DEAD);
301 multilink_master = 0;
304static void make_bundle_links(
int append)
311 key.dptr = blinks_id;
313 slprintf(
entry,
sizeof(
entry),
"%s;", db_key);
316 rec = tdb_fetch(pppdb,
key);
317 if (rec.dptr !=
NULL && rec.dsize > 0) {
318 rec.dptr[rec.dsize-1] = 0;
321 warn(
"link entry already exists in tdb");
327 novm(
"bundle link list");
328 slprintf(
p,
l,
"%s%s", rec.dptr,
entry);
330 warn(
"bundle link list not found");
332 if (rec.dptr !=
NULL)
337 if (tdb_store(pppdb,
key, rec, TDB_REPLACE))
338 error(
"couldn't %s bundle link list",
339 append?
"update":
"create");
344static void remove_bundle_link()
351 key.dptr = blinks_id;
353 slprintf(
entry,
sizeof(
entry),
"%s;", db_key);
355 rec = tdb_fetch(pppdb,
key);
356 if (rec.dptr ==
NULL || rec.dsize <= 0) {
357 if (rec.dptr !=
NULL)
361 rec.dptr[rec.dsize-1] = 0;
367 rec.dsize =
p - rec.dptr +
l;
368 if (tdb_store(pppdb,
key, rec, TDB_REPLACE))
369 error(
"couldn't update bundle link list (removal)");
374static void iterate_bundle_links(
void (*
func)(
char *))
376 TDB_DATA
key, rec, pp;
379 key.dptr = blinks_id;
381 rec = tdb_fetch(pppdb,
key);
382 if (rec.dptr ==
NULL || rec.dsize <= 0) {
383 error(
"bundle link list not found (iterating list)");
384 if (rec.dptr !=
NULL)
394 pp = tdb_fetch(pppdb,
key);
395 if (pp.dptr !=
NULL && pp.dsize > 0) {
396 pp.dptr[pp.dsize-1] = 0;
419 if (endp !=
p && (*endp == 0 || *endp ==
';')) {
439 slprintf(ifkey,
sizeof(ifkey),
"IFNAME=ppp%d",
unit);
442 vd = tdb_fetch(pppdb, kd);
443 if (vd.dptr !=
NULL) {
444 ret = vd.dsize ==
key.dsize
445 &&
memcmp(vd.dptr,
key.dptr, vd.dsize) == 0;
452get_default_epdisc(ep)
460 p = get_first_ethernet();
461 if (
p != 0 && get_if_hwaddr(ep->value,
p) >= 0) {
473 if (!LOCAL_IP_ADDR(
addr)) {
475 set_ip_epdisc(ep,
addr);
488static char *endp_class_names[] = {
489 "null",
"local",
"IP",
"MAC",
"magic",
"phone"
496 static char str[MAX_ENDP_LEN*3+8];
501 if (ep->class == EPD_NULL && ep->length == 0)
503 if (ep->class == EPD_IP && ep->length == 4) {
513 if (ep->class == EPD_MAC && ep->length == 6)
515 else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0)
518 if (ep->class <= EPD_PHONENUM)
519 q += slprintf(
q,
sizeof(
str)-1,
"%s",
520 endp_class_names[ep->class]);
522 q += slprintf(
q,
sizeof(
str)-1,
"%d", ep->class);
524 for (
i = 0;
i < ep->length &&
i < MAX_ENDP_LEN; ++
i) {
525 if ((
i &
mask) == 0) {
529 q += slprintf(
q,
str +
sizeof(
str) -
q,
"%.2x", ep->value[
i]);
534static int hexc_val(
int c)
544str_to_epdisc(ep,
str)
551 for (
i = EPD_NULL;
i <= EPD_PHONENUM; ++
i) {
552 int sl =
strlen(endp_class_names[
i]);
558 if (
i > EPD_PHONENUM) {
570 if (*
str !=
':' && *
str !=
'.')
577 if (
i == 0 ||
str[
i] != 0)
579 set_ip_epdisc(ep,
addr);
582 if (
i == EPD_MAC && get_if_hwaddr(ep->value,
str) >= 0) {
588 for (
l = 0;
l < MAX_ENDP_LEN; ++
l) {
597 ep->value[
l] = hexc_val(*
str++);
599 ep->value[
l] = (ep->value[
l] << 4) + hexc_val(*
str++);
600 if (*
str ==
':' || *
str ==
'.')
603 if (*
str != 0 || (ep->class == EPD_MAC &&
l != 6))
char * strstr(char *String1, char *String2)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
ACPI_SIZE strlen(const char *String)
char * strchr(const char *String, int ch)
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
GLdouble GLdouble GLdouble GLdouble q
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
static void append(struct dump_context *dc, const void *data, unsigned size)
#define memmove(s1, s2, n)
png_const_structrp png_const_inforp int * unit
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid