static GVariant * parse_res_soa (guchar *answer, guchar *end, guchar **p) { gchar mnamebuf[1024]; gchar rnamebuf[1024]; guint32 serial, refresh, retry, expire, ttl; *p += dn_expand (answer, end, *p, mnamebuf, sizeof (mnamebuf)); *p += dn_expand (answer, end, *p, rnamebuf, sizeof (rnamebuf)); GETLONG (serial, *p); GETLONG (refresh, *p); GETLONG (retry, *p); GETLONG (expire, *p); GETLONG (ttl, *p); return g_variant_new ("(ssuuuuu)", mnamebuf, rnamebuf, serial, refresh, retry, expire, ttl); }
static VarEntry * add_private(ClipMachine * ClipMachineMemory, long hash) { long *p; VarEntry *vp, *np; ClipFrame *fp; if (ClipMachineMemory->inMacro) fp = ClipMachineMemory->inMacro; else fp = ClipMachineMemory->fp; if (fp) { p = fp->privates_of_ClipFrame; if (p) { int n; long c; for (n = *p, p++; n >= 0; n--, p++) if (hash == GETLONG(p)) { vp = (VarEntry *) HashTable_fetch(ClipMachineMemory->privates, hash); if (vp) return vp; } p = fp->privates_of_ClipFrame; c = GETLONG(p); p = (long *) realloc(p, (c + 2) * sizeof(long)); SETLONG(p, c + 1); SETLONG(p + c + 1, hash); fp->privates_of_ClipFrame = p; } else { p = fp->privates_of_ClipFrame = (long *) malloc(sizeof(long) * 2); SETLONG(p, 1); SETLONG(p + 1, hash); } } vp = (VarEntry *) HashTable_fetch(ClipMachineMemory->privates, hash); np = new_VarEntry(hash); if (!vp) HashTable_insert(ClipMachineMemory->privates, np, hash); else { np->VarEntry_next_of_VarEntry = vp; HashTable_remove(ClipMachineMemory->privates, hash); HashTable_store(ClipMachineMemory->privates, np, hash); } return np; }
static int conffat(Fat *fat, void *buf) { Pbs *p = buf; uint fatsize, volsize, datasize, reserved; uint ver, dirsize, dirents, clusters; /* sanity check */ if(GETSHORT(p->sectsize) != Sectsz){ print("sectsize != 512\r\n"); halt(); } /* load values from fat */ fatsize = GETSHORT(p->fatsize); if(fatsize == 0) fatsize = GETLONG(p->fat32.fatsize); volsize = GETSHORT(p->volsize); if(volsize == 0) volsize = GETLONG(p->bigvolsize); reserved = GETSHORT(p->nreserv); dirents = GETSHORT(p->rootsize); dirsize = (dirents * Dirsz + Sectsz - 1) / Sectsz; datasize = volsize - (reserved + fatsize * p->nfats + dirsize); clusters = datasize / p->clustsize; /* determine fat type */ if(clusters < 4085) ver = Fat12; else if(clusters < 65525) ver = Fat16; else ver = Fat32; /* another check */ if(ver == Fat12){ print("TODO: implement FAT12\r\n"); halt(); } /* fill FAT descriptor */ fat->ver = ver; fat->dirents = dirents; fat->clustsize = p->clustsize; fat->fatlba = fat->partlba + reserved; fat->dirstart = fat->fatlba + fatsize * p->nfats; if(ver == Fat32){ fat->datalba = fat->dirstart; fat->dirstart = GETLONG(p->fat32.rootclust); fat->eofmark = 0xffffff; }else{ fat->datalba = fat->dirstart + dirsize; fat->eofmark = 0xfff; } return 0; }
static void get_func(char *modbeg, int no, char **fp) { long funcOffs = GETLONG(F_OFFS(modbeg, 5, 4, 0)); long *bp = (long *) (modbeg + funcOffs); bp += 2 * no; ++bp; *fp = modbeg + GETLONG(bp); }
static void make_func(struct ClipFile *file, ClipCodeVar * dest, long *hash) { char *modbeg = M_OFFS(file->body, 2, 0); dest->t.type = PCODE_t; dest->t.flags = F_NONE; dest->u.block->file = file; SETLONG(hash, GETLONG(file->pos + 0)); dest->u.block->func = modbeg + GETLONG(file->pos + 1); }
static int lcp_ext(fsm *f, int code, int id, u_char *inp, int inlen) { lcp *_this; uint32_t magic; char buf[256]; int i, len; _this = &f->ppp->lcp; switch (code) { case IDENTIFICATION: /* RFC 1570 */ if (inlen > 4) { GETLONG(magic, inp); inlen -= 4; memset(buf, 0, sizeof(buf)); len = MIN(inlen, sizeof(buf) - 1); memcpy(buf, inp, len); buf[len] = '\0'; for (i = 0; i < len; i++) { if (!isprint((unsigned char)buf[i])) buf[i] = '.'; } fsm_log(f, LOG_INFO, "RecvId magic=%08x text=%s", magic, buf); } return 1; case PROTREJ: lcp_rcoderej(f, inp, inlen); return 1; case ECHOREP: if (f->state == OPENED) { if (inlen >= 4) { GETLONG(magic, inp); if (_this->peer_magic_number == magic) { _this->echo_failures = 0; lcp_reset_timeout(_this); } } } return 1; case ECHOREQ: if (f->state == OPENED) return lcp_rechoreq(f, id, inp, inlen); return 1; } return 0; }
void creliable (unsigned char *message, int size) { int pos = 0; while (pos < size) { long rpos1; int size; GETLONG ((message + pos), rpos1); if (rpos1 > rpos + 1) { printf ("Fatal error in transfering reliable messages!\n" "Game may become VERY unstable..please contact author \n"); return; } GETSHORT ((message + pos + 4), size); if (rpos1 <= rpos) { pos += size; continue; } rpos = rpos1; ctable[message[pos + 6]].func ((message + pos + 7), size - 7); pos += size; } }
u_int32_t _getlong(const u_char *msgp) { u_int32_t u; GETLONG(u, msgp); return u; }
static void remove_private_vect(ClipMachine * ClipMachineMemory, int num, void *vect) { long *lp = (long *) vect; for (; num > 0; --num, ++lp) { long hash = GETLONG(lp); VarEntry *vp = (VarEntry *) HashTable_fetch(ClipMachineMemory->privates, hash); if (!vp) continue; if (vp->VarEntry_next_of_VarEntry) { HashTable_remove(ClipMachineMemory->privates, hash); HashTable_store(ClipMachineMemory->privates, vp->VarEntry_next_of_VarEntry, hash); vp->VarEntry_next_of_VarEntry = 0; } else { HashTable_remove(ClipMachineMemory->privates, hash); } delete_VarEntry(ClipMachineMemory, vp); } }
u_int32_t ircd_getlong(const u_char *msgp) { register u_int32_t u; GETLONG(u, msgp); return (u); }
void process_message (void) { int bytes, pos = 4; long scount; if (!SocketReadable (sock)) return; GetSocketError (sock); if ((bytes = DgramReceiveAny (sock, (char *) ibuffer, BUFFERSIZE)) <= 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || bytes >= 0) { GetSocketError (sock); return; } CQuit ("Can't receive server's message\n"); SocketClose (sock); } GETLONG (ibuffer, scount); csetrrcount (scount); while (pos + 2 < bytes) { int size; GETSHORT (ibuffer + pos, size); if (pos + size <= bytes) { ctable[ibuffer[pos + 2]].func ((ibuffer + pos + 3), size - 3); } pos += size; } }
int decode_smb(u_char *buf, int len, u_char *obuf, int olen) { struct smbhdr *smb; int i, j, k; u_char *p, *q, *end; char *user, *pass; obuf[0] = '\0'; /* Skip NetBIOS session request. */ if (len < 4 || buf[0] != 0x81) return (0); buf += 2; GETSHORT(i, buf); len -= 4; if (len < i) return (0); buf += i; len -= i; end = buf + len; /* Parse SMBs. */ for (p = buf; p < end; p += i) { GETLONG(i, p); if (i > end - p || i < sizeof(*smb) + 32) continue; smb = (struct smbhdr *)p; if (memcmp(smb->proto, "\xffSMB", 4) != 0 || smb->cmd != 0x73) continue; user = pass = NULL; q = (u_char *)(smb + 1); if (*q == 10) { /* Pre NT LM 0.12 */ q += 15; j = pletohs(q); q += 2; if (j > i - (sizeof(*smb) + 15 + 6)) continue; pass = q + 6; user = pass + j; } else if (*q == 13) { /* NT LM 0.12 */ q += 15; j = pletohs(q); q += 2; k = pletohs(q); if (j > i - ((q - p) + 12) || k > i - ((q - p) + 11)) continue; pass = q + 12; user = pass + j + k; } else continue; /* XXX - skip null IPC sessions, etc. */ if (user && pass && strlen(user) && is_ascii_string(pass, j - 1)) { strlcat(obuf, user, olen); strlcat(obuf, " ", olen); strlcat(obuf, pass, olen); strlcat(obuf, "\n", olen); } } return (strlen(obuf)); }
static int findfat(Fat *fat, int drive, ulong xbase, ulong lba) { struct { uchar status; uchar bchs[3]; uchar typ; uchar echs[3]; uchar lba[4]; uchar len[4]; } *p; uchar buf[Sectsz]; int i; if(xbase == 0) xbase = lba; if(readsect(drive, lba, buf)) return -1; if(buf[0x1fe] != 0x55 || buf[0x1ff] != 0xAA) return -1; p = (void*)&buf[0x1be]; for(i=0; i<4; i++){ switch(p[i].typ){ case 0x05: case 0x0f: case 0x85: /* extended partitions */ if(!findfat(fat, drive, xbase, xbase + GETLONG(p[i].lba))) return 0; /* no break */ case 0x00: continue; default: if(p[i].status != 0x80) continue; fat->drive = drive; fat->partlba = lba + GETLONG(p[i].lba); if(readsect(drive, fat->partlba, buf)) continue; if(conffat(fat, buf)) continue; return 0; } } return -1; }
static int rrextract(u_char *msg, int msglen, u_char *rrp, u_char *dname, int namelen) { /* cp is used to read data from rrp[] (the Resource Record) * cp1 is used to write data into data[] * However, we sometimes abuse cp1 and use it for reading too. :-/ */ u_char *eom, *cp, *cp1, *rdatap; u_int class, type, dlen; int n; long origTTL; u_char data[MAXDATA*2+SPACE_FOR_VARS]; data [(MAXDATA*2)-1+SPACE_FOR_VARS] = EOS; cp = rrp; eom = msg + msglen; GETSHORT(dlen, cp); BOUNDS_CHECK(cp, dlen); /* Begin case T_SIG: */ /* Just read one variable --- the original reads several. */ BOUNDS_CHECK(cp, SPACE_FOR_VARS); cp1 = cp; GETLONG(origTTL, cp1); /* Skip checks on times which are present in the original. */ /* Copy over initial fields, which we read above. */ cp1 = (u_char *)data; BOUNDS_CHECK(cp, SPACE_FOR_VARS); memcpy(cp1, cp, SPACE_FOR_VARS); cp += SPACE_FOR_VARS; cp1 += SPACE_FOR_VARS; /* Expand the domain name, set cp1 past the end of the uncompressed * domain name. */ n = dn_expand(msg, eom, cp, (char *)cp1, (sizeof data)); if (n < 0) { return (-1); } cp += n; cp1 += strlen((char*)cp1)+1; /* Figure out the length of the "signature" to copy over and copy it. */ n = dlen - (SPACE_FOR_VARS + n); if (n > (sizeof data) - (cp1 - (u_char *)data)) { return (-1); /* out of room! */ } /* OK */ r_memcpy(cp1, cp, n); return 0; }
CLIP_DLLEXPORT int _clip_load_inits(ClipMachine * ClipMachineMemory, ClipFile * file) { long funcOffs = GETLONG(M_OFFS(file->body_of_ClipFile, 7, 4)); char *modbeg = M_OFFS(file->body_of_ClipFile, 2, 0); int pubnum = GETLONG(M_OFFS(file->body_of_ClipFile, 4, 2)); int initnum = GETSHORT(M_OFFS(file->body_of_ClipFile, 8, 4)); int exitnum = GETSHORT(M_OFFS(file->body_of_ClipFile, 8, 5)); ClipBlock b; ClipCodeVar c; int i; long hash; c.union_of_ClipCodeVar.ClipBlock_block_of_ClipCodeVar = &b; file->pos_of_ClipFile = (long *) (modbeg + funcOffs); file->pos_of_ClipFile += 2 * pubnum; /*file->end = file->pos + 2 * num; */ for (i = 0; i < initnum; ++i) { make_func(file, &c, &hash); file->pos_of_ClipFile += 2; _clip_main_code(ClipMachineMemory, c.union_of_ClipCodeVar.ClipBlock_block_of_ClipCodeVar, _clip_argc, _clip_argv, _clip_envp); } for (i = 0; i < exitnum; ++i) { make_func(file, &c, &hash); file->pos_of_ClipFile += 2; ClipMachineMemory->exits = (ClipBlock *) realloc(ClipMachineMemory->exits, (ClipMachineMemory->nexits + 1) * sizeof(ClipBlock)); ClipMachineMemory->exits[ClipMachineMemory->nexits] = *c.union_of_ClipCodeVar.ClipBlock_block_of_ClipCodeVar; ++file->refCount_of_ClipFile; ++ClipMachineMemory->nexits; } return 0; }
static void get_str(char *modbeg, int no, char **sp, int *len) { short strOffs = GETSHORT(F_OFFS(modbeg, 4, 3, 0)); char *bp = (modbeg + strOffs); bp += 2 * no * sizeof(long); SETINT(len, GET_LONG(bp)); *sp = modbeg + GETLONG(bp); }
int _clip_first_File(struct ClipFile *file, ClipCodeVar * dest, long *hash) { long funcOffs = GETLONG(M_OFFS(file->body, 7, 4)); char *modbeg = M_OFFS(file->body, 2, 0); int pubnum = GETLONG(M_OFFS(file->body, 4, 2)); /*int initnum = GETLONG( M_OFFS(file->body, 7, 5)); */ /*int exitnum = GETLONG( M_OFFS(file->body, 7, 6)); */ int num; num = pubnum; file->pos = (long *) (modbeg + funcOffs); file->end = file->pos + 2 * num; if (num == 0) return 0; make_func(file, dest, hash); file->pos += 2; return 1; }
static void get_static(ClipMachine * mp, ClipFile * file, ClipVar * statics, char *modbeg, int no, ClipVar ** dest) { if (!statics->t.count) { ClipBlock init; long initOffs = GETLONG(F_OFFS(modbeg, 4, 4, 0)); statics->t.count = 1; init.file = file; init.func = modbeg + initOffs; _clip_code_func(mp, &init, 0, 0, 0); } *dest = statics + no + 1; }
static void get_static(ClipMachine * ClipMachineMemory, ClipFile * file, ClipVar * statics, char *modbeg, int no, ClipVar ** dest) { if (!statics->ClipType_t_of_ClipVar.count_of_ClipType) { ClipBlock init; long initOffs = GETLONG(F_OFFS(modbeg, 4, 4, 0)); statics->ClipType_t_of_ClipVar.count_of_ClipType = 1; init.file_of_ClipBlock = file; init.function_of_ClipBlock = modbeg + initOffs; _clip_code_func(ClipMachineMemory, &init, 0, 0, 0); } *dest = statics + no + 1; }
static void print_dim(ClipMachine * ClipMachineMemory, char *buf, int size, int dim, int Dim, long *Vect) { char *s = buf, *e = buf + size - 20; int i; for (i = 0, *s = 0; i < Dim - dim && s < e; ++i) { char bb[64]; s = s + strlen(s); _clip_hash_name(ClipMachineMemory, GETLONG(Vect + i), bb, sizeof(bb)); sprintf(s, "[%s]", bb); } }
static void ssh_strlcat(char *dst, int size, char *src, int len) { char *p; u_int32_t i; for (p = dst; *p != '\0'; p++) ; size -= (p - dst - 1); GETLONG(i, src); i = MIN(i, len); i = MIN(i, size); memcpy(p, src, i); p[i] = '\0'; }
void csetrrcount (long scount) { int size, pos = 0, count; if (scount <= rrcount) return; /*Old repeated message */ do { GETLONG ((rbuffer + pos), count); GETSHORT ((rbuffer + pos) + 4, size); pos += size; } while (count < scount); memmove (rbuffer, rbuffer + pos, rposition - pos); rposition -= pos; rrcount = scount; }
static ulong readnext(File *fp, ulong clust) { Fat *fat = fp->fat; uint b = fat->ver; ulong sect, off; sect = clust * b / Sectsz; off = clust * b % Sectsz; if(readsect(fat->drive, fat->fatlba + sect, fp->buf)) memset(fp->buf, 0xff, 4); switch(fat->ver){ case Fat16: return GETSHORT(&fp->buf[off]); case Fat32: return GETLONG(&fp->buf[off])& 0x0fffffff; } return 0; }
CLIP_DLLEXPORT int _clip_aset(ClipMachine * ClipMachineMemory, ClipVar * ap, ClipVar * vp, int ndim, long *dims) { int c; long ind; ClipVar *app; ap = _clip_vptr(ap); if ((ap->ClipType_t_of_ClipVar.ClipVartype_type_of_ClipType != ARRAY_type_of_ClipVarType && ap->ClipType_t_of_ClipVar.ClipVartype_type_of_ClipType != MAP_type_of_ClipVarType) || !ndim) { _clip_trap_printf(ClipMachineMemory, __file__, __LINE__, "aset for non-array object"); return _clip_call_errblock(ClipMachineMemory, 1); } if (ap->ClipType_t_of_ClipVar.ClipVartype_type_of_ClipType == MAP_type_of_ClipVarType) { app = _clip_mget(ClipMachineMemory, ap, dims[0]); } else { c = ap->ClipArrVar_a_of_ClipVar.count_of_ClipArrVar; ind = GETLONG(dims); if (ind < 0 || ind >= c) { _clip_trap_printf(ClipMachineMemory, __file__, __LINE__, "index for aset is out-of range: ind=%d, count=%d", ind + 1, c); return _clip_call_errblock(ClipMachineMemory, 1); } app = ap->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar + ind; } if (ndim > 1) { return _clip_aset(ClipMachineMemory, app, vp, ndim - 1, dims + 1); } /*_clip_destroy(ClipMachineMemory, app);*/ return _clip_mclone(ClipMachineMemory, app, vp); }
static int get_string(char *dst, int len, u_char **pp, int *lenp) { long i; if (*lenp < 4) { errno = EINVAL; return (-1); } GETLONG(i, *pp); *lenp -= 4; if (*lenp < i || len < i) { errno = EINVAL; return (-1); } memcpy(dst, *pp, i); *pp += i; *lenp -= i; return (0); }
static int search_long(long *coll, int count, long key) { int l, h, i; long c; l = 0; h = count - 1; while (l <= h) { i = (l + h) >> 1; if ((c = GETLONG(coll+i)) < key) l = i + 1; else { if (c == key) return i; h = i - 1; } } return -1; }
/** * This function is called when an input packet come from network(tun). * Currently, it assumes that it input IPv4 packet. */ static void npppd_iface_network_input(npppd_iface *_this, u_char *pktp, int lpktp) { uint32_t af; if (lpktp < sizeof(uint32_t)) { npppd_iface_log(_this, LOG_ERR, "Received short packet."); return; } GETLONG(af, pktp); lpktp -= sizeof(uint32_t); switch (af) { case AF_INET: npppd_iface_network_input_ipv4(_this, pktp, lpktp); break; default: NPPPD_IFACE_ASSERT(0); break; } }
static unsigned char *php_parserr(unsigned char *cp, unsigned char* end, querybuf *answer, int type_to_fetch, bool store, Array &subarray) { unsigned short type, cls ATTRIBUTE_UNUSED, dlen; unsigned long ttl; int64_t n, i; unsigned short s; unsigned char *tp, *p; char name[MAXHOSTNAMELEN]; int have_v6_break = 0, in_v6_break = 0; n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, sizeof(name) - 2); if (n < 0) { return NULL; } cp += n; CHECKCP(10); GETSHORT(type, cp); GETSHORT(cls, cp); GETLONG(ttl, cp); GETSHORT(dlen, cp); CHECKCP(dlen); if (type_to_fetch != T_ANY && type != type_to_fetch) { cp += dlen; return cp; } if (!store) { cp += dlen; return cp; } subarray.set(s_host, String(name, CopyString)); switch (type) { case DNS_T_A: CHECKCP(4); subarray.set(s_type, s_A); snprintf(name, sizeof(name), "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]); subarray.set(s_ip, String(name, CopyString)); cp += dlen; break; case DNS_T_MX: CHECKCP(2); subarray.set(s_type, s_MX); GETSHORT(n, cp); subarray.set(s_pri, n); /* no break; */ case DNS_T_CNAME: if (type == DNS_T_CNAME) { subarray.set(s_type, s_CNAME); } /* no break; */ case DNS_T_NS: if (type == DNS_T_NS) { subarray.set(s_type, s_NS); } /* no break; */ case DNS_T_PTR: if (type == DNS_T_PTR) { subarray.set(s_type, s_PTR); } n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } cp += n; subarray.set(s_target, String(name, CopyString)); break; case DNS_T_HINFO: /* See RFC 1010 for values */ subarray.set(s_type, s_HINFO); CHECKCP(1); n = *cp & 0xFF; cp++; CHECKCP(n); subarray.set(s_cpu, String((const char *)cp, n, CopyString)); cp += n; CHECKCP(1); n = *cp & 0xFF; cp++; CHECKCP(n); subarray.set(s_os, String((const char *)cp, n, CopyString)); cp += n; break; case DNS_T_TXT: { int l1 = 0, l2 = 0; String s = String(dlen, ReserveString); tp = (unsigned char *)s.bufferSlice().ptr; while (l1 < dlen) { n = cp[l1]; if ((n + l1) > dlen) { // bad record, don't set anything break; } memcpy(tp + l1 , cp + l1 + 1, n); l1 = l1 + n + 1; l2 = l2 + n; } s.setSize(l2); cp += dlen; subarray.set(s_type, s_TXT); subarray.set(s_txt, s); break; } case DNS_T_SOA: subarray.set(s_type, s_SOA); n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2); if (n < 0) { return NULL; } cp += n; subarray.set(s_mname, String(name, CopyString)); n = dn_expand(answer->qb2, end, cp, name, (sizeof name) -2); if (n < 0) { return NULL; } cp += n; subarray.set(s_rname, String(name, CopyString)); CHECKCP(5*4); GETLONG(n, cp); subarray.set(s_serial, n); GETLONG(n, cp); subarray.set(s_refresh, n); GETLONG(n, cp); subarray.set(s_retry, n); GETLONG(n, cp); subarray.set(s_expire, n); GETLONG(n, cp); subarray.set(s_minimum_ttl, n); break; case DNS_T_AAAA: tp = (unsigned char *)name; CHECKCP(8*2); for (i = 0; i < 8; i++) { GETSHORT(s, cp); if (s != 0) { if (tp > (u_char *)name) { in_v6_break = 0; tp[0] = ':'; tp++; } tp += sprintf((char *)tp, "%x", s); } else { if (!have_v6_break) { have_v6_break = 1; in_v6_break = 1; tp[0] = ':'; tp++; } else if (!in_v6_break) { tp[0] = ':'; tp++; tp[0] = '0'; tp++; } } } if (have_v6_break && in_v6_break) { tp[0] = ':'; tp++; } tp[0] = '\0'; subarray.set(s_type, s_AAAA); subarray.set(s_ipv6, String(name, CopyString)); break; case DNS_T_A6: p = cp; subarray.set(s_type, s_A6); CHECKCP(1); n = ((int)cp[0]) & 0xFF; cp++; subarray.set(s_masklen, n); tp = (unsigned char *)name; if (n > 15) { have_v6_break = 1; in_v6_break = 1; tp[0] = ':'; tp++; } if (n % 16 > 8) { /* Partial short */ if (cp[0] != 0) { if (tp > (u_char *)name) { in_v6_break = 0; tp[0] = ':'; tp++; } sprintf((char *)tp, "%x", cp[0] & 0xFF); } else { if (!have_v6_break) { have_v6_break = 1; in_v6_break = 1; tp[0] = ':'; tp++; } else if (!in_v6_break) { tp[0] = ':'; tp++; tp[0] = '0'; tp++; } } cp++; } for (i = (n + 8)/16; i < 8; i++) { CHECKCP(2); GETSHORT(s, cp); if (s != 0) { if (tp > (u_char *)name) { in_v6_break = 0; tp[0] = ':'; tp++; } tp += sprintf((char*)tp,"%x",s); } else { if (!have_v6_break) { have_v6_break = 1; in_v6_break = 1; tp[0] = ':'; tp++; } else if (!in_v6_break) { tp[0] = ':'; tp++; tp[0] = '0'; tp++; } } } if (have_v6_break && in_v6_break) { tp[0] = ':'; tp++; } tp[0] = '\0'; subarray.set(s_ipv6, String(name, CopyString)); if (cp < p + dlen) { n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } cp += n; subarray.set(s_chain, String(name, CopyString)); } break; case DNS_T_SRV: CHECKCP(3*2); subarray.set(s_type, s_SRV); GETSHORT(n, cp); subarray.set(s_pri, n); GETSHORT(n, cp); subarray.set(s_weight, n); GETSHORT(n, cp); subarray.set(s_port, n); n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } cp += n; subarray.set(s_target, String(name, CopyString)); break; case DNS_T_NAPTR: CHECKCP(2*2); subarray.set(s_type, s_NAPTR); GETSHORT(n, cp); subarray.set(s_order, n); GETSHORT(n, cp); subarray.set(s_pref, n); CHECKCP(1); n = (cp[0] & 0xFF); ++cp; CHECKCP(n); subarray.set(s_flags, String((const char *)cp, n, CopyString)); cp += n; CHECKCP(1); n = (cp[0] & 0xFF); ++cp; CHECKCP(n); subarray.set(s_services, String((const char *)cp, n, CopyString)); cp += n; CHECKCP(1); n = (cp[0] & 0xFF); ++cp; CHECKCP(n); subarray.set(s_regex, String((const char *)cp, n, CopyString)); cp += n; n = dn_expand(answer->qb2, end, cp, name, (sizeof name) - 2); if (n < 0) { return NULL; } cp += n; subarray.set(s_replacement, String(name, CopyString)); break; default: cp += dlen; } subarray.set(s_class, s_IN); subarray.set(s_ttl, (int)ttl); return cp; }
/** receiving ConfAck. */ static int lcp_ackci(fsm *f, u_char *inp, int inlen) { int chapalg, authproto, type, len, mru, magic; u_char *inp0; #define remlen() (inlen - (inp - inp0)) #define LCP_OPT_ACCEPTED(opt) \ if (!psm_opt_is_requested(&f->ppp->lcp, opt)) \ goto fail; \ psm_opt_set_accepted(&f->ppp->lcp, opt, 1); f->ppp->lcp.recv_ress++; inp0 = inp; while (remlen() >= 2) { GETCHAR(type, inp); GETCHAR(len, inp); if (len <= 0 || remlen() + 2 < len) goto fail; switch (type) { case PPP_LCP_MAGICNUMBER: if (len != 6) goto fail; GETLONG(magic, inp); if (f->ppp->lcp.magic_number != magic) goto fail; break; case PPP_LCP_MRU: if (len != 4) goto fail; LCP_OPT_ACCEPTED(mru); GETSHORT(mru, inp); break; case PPP_LCP_AUTH_PROTOCOL: if (len < 4) goto fail; GETSHORT(authproto, inp); switch (authproto) { case PPP_AUTH_PAP: if (len != 4) goto fail; LCP_OPT_ACCEPTED(pap); break; case PPP_AUTH_CHAP: if (len != 5) goto fail; GETCHAR(chapalg, inp); switch (chapalg) { case PPP_AUTH_CHAP_MD5: LCP_OPT_ACCEPTED(chap); break; case PPP_AUTH_CHAP_MS: LCP_OPT_ACCEPTED(chapms); break; case PPP_AUTH_CHAP_MS_V2: LCP_OPT_ACCEPTED(chapms_v2); break; } break; case PPP_AUTH_EAP: if (len != 4) goto fail; LCP_OPT_ACCEPTED(eap); break; } break; /* * As RFC1661, ConfRej must be used for boolean options, but * at least RouterTester uses ConfNak for them. */ case PPP_LCP_PFC: if (len != 2) goto fail; LCP_OPT_ACCEPTED(pfc); break; case PPP_LCP_ACFC: if (len != 2) goto fail; LCP_OPT_ACCEPTED(acfc); break; default: goto fail; } } return 1; fail: fsm_log(f, LOG_ERR, "Received unexpected ConfAck."); if (debug_get_debugfp() != NULL) show_hd(debug_get_debugfp(), inp, remlen()); return 0; #undef LCP_OPT_ACCEPTED }
static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { uint32_t magic; int type, len, rcode, mru, lrej; u_char *inp0, *rejbuf, *nakbuf, *nakbuf0; lcp *_this; _this = &f->ppp->lcp; rejbuf = NULL; rcode = -1; inp0 = inp; lrej = 0; if ((rejbuf = malloc(*lenp)) == NULL) return -1; if ((nakbuf0 = malloc(*lenp)) == NULL) { free(rejbuf); return -1; } nakbuf = nakbuf0; #define remlen() (*lenp - (inp - inp0)) #define LCP_OPT_PEER_ACCEPTED(opt) \ psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1); f->ppp->lcp.recv_reqs++; while (remlen() >= 2) { GETCHAR(type, inp); GETCHAR(len, inp); if (len <= 0 || remlen() + 2 < len) goto fail; switch (type) { case PPP_LCP_MRU: if (len != 4) goto fail; GETSHORT(mru, inp); f->ppp->peer_mru = mru; if (mru < NPPPD_MIN_MRU) { if (reject_if_disagree) { inp -= 2; goto reject; } if (lrej > 0) { /* if there is a reject, will send Rej, not send Nak. */ } else { inp -= 2; memcpy(nakbuf, inp, len); nakbuf += len; inp += 2; PUTSHORT(f->ppp->mru, nakbuf); rcode = CONFNAK; } } else LCP_OPT_PEER_ACCEPTED(mru); break; case PPP_LCP_MAGICNUMBER: if (len != 6) goto fail; GETLONG(magic, inp); if (magic == _this->magic_number) { inp -= 4; goto reject; } _this->peer_magic_number = magic; break; case PPP_LCP_PFC: if (len != 2) goto fail; LCP_OPT_PEER_ACCEPTED(pfc); break; case PPP_LCP_ACFC: if (len != 2) goto fail; LCP_OPT_PEER_ACCEPTED(acfc); break; case PPP_LCP_AUTH_PROTOCOL: /* currently never authenticate. */ case PPP_LCP_QUALITY_PROTOCOL: /* not used */ default: reject: inp -= 2; memcpy(rejbuf + lrej, inp, len); lrej += len; inp += len; rcode = CONFREJ; } continue; } if (rcode == -1) rcode = CONFACK; fail: switch (rcode) { case CONFREJ: memcpy(inp0, rejbuf, lrej); *lenp = lrej; break; case CONFNAK: memcpy(inp0, nakbuf0, nakbuf - nakbuf0); *lenp = nakbuf - nakbuf0; break; } if (rcode != CONFACK) { psm_peer_opt_set_accepted(&f->ppp->lcp, mru, 0); psm_peer_opt_set_accepted(&f->ppp->lcp, pfc, 0); psm_peer_opt_set_accepted(&f->ppp->lcp, acfc, 0); } if (rejbuf != NULL) free(rejbuf); if (nakbuf0 != NULL) free(nakbuf0); return rcode; #undef remlen #undef LCP_OPT_PEER_ACCEPTED }