void pack_in6aliasreq(struct in6_aliasreq *ip6req, ip_t *ip, struct in6_addr *in6dest, char *ifname) { struct sockaddr_in6 *sin6; /* set IP address */ sin6 = (struct sockaddr_in6 *)&ip6req->ifra_addr; sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); memcpy(&sin6->sin6_addr, &ip->addr.in6, sizeof(struct in6_addr)); /* set prefixmask */ sin6 = (struct sockaddr_in6 *)&ip6req->ifra_prefixmask; sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); prefixlen(ip->bitlen, sin6); /* set infinite lifetime */ ip6req->ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; ip6req->ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; /* set destination address */ if (!IN6_IS_ADDR_UNSPECIFIED(in6dest)) { sin6 = (struct sockaddr_in6 *)&ip6req->ifra_dstaddr; sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(struct sockaddr_in6); memcpy(&sin6->sin6_addr, in6dest, sizeof(struct in6_addr)); } /* set interface name */ strlcpy(ip6req->ifra_name, ifname, sizeof(ip6req->ifra_name)); }
/* * look through a containing subset */ static Ndbtuple* subnet(Ndb *db, uint8_t *net, Ndbtuple *f, int prefix) { Ndbs s; Ndbtuple *t, *nt, *xt; char netstr[128]; uint8_t mask[IPaddrlen]; int masklen; t = nil; sprint(netstr, "%I", net); nt = ndbsearch(db, &s, "ip", netstr); while(nt != nil){ xt = ndbfindattr(nt, nt, "ipnet"); if(xt){ xt = ndbfindattr(nt, nt, "ipmask"); if(xt) parseipmask(mask, xt->val); else ipmove(mask, defmask(net)); masklen = prefixlen(mask); if(masklen <= prefix){ t = ndbconcatenate(t, filter(db, nt, f)); nt = nil; } } ndbfree(nt); nt = ndbsnext(&s, "ip", netstr); } ndbsetmalloctag(t, getcallerpc(&db)); return t; }
/* Result is pool'd*/ char* prefixtostring(List* prefix, char* separator) { int slen=0; int plen; int i; char* result; if(prefix == NULL) return pooldup(""); plen = prefixlen(prefix); if(plen == 0) { /* root prefix*/ slen=0; /* slen += strlen(separator);*/ slen++; /* for null terminator*/ result = poolalloc(slen); result[0] = '\0'; /*strcat(result,separator);*/ } else { for(i=0;i<plen;i++) { Symbol* sym = (Symbol*)listget(prefix,i); slen += (strlen(separator)+strlen(sym->name)); } slen++; /* for null terminator*/ result = poolalloc(slen); result[0] = '\0'; for(i=0;i<plen;i++) { Symbol* sym = (Symbol*)listget(prefix,i); strcat(result,separator); strcat(result,sym->name); /* append "/<prefix[i]>"*/ } } return result; }
int get_prefixlen(char *buf) { struct rt_msghdr *rtm = (struct rt_msghdr *)buf; struct sockaddr *sa, *rti_info[RTAX_MAX]; char *p, *lim; sa = (struct sockaddr *)(rtm + 1); get_rtaddrs(rtm->rtm_addrs, sa, rti_info); sa = rti_info[RTAX_NETMASK]; p = (char *)(&SIN6(sa)->sin6_addr); lim = (char *)sa + sa->sa_len; return prefixlen(p, lim); }
static void Write_words (FILE * f, DictData * dd) { int i; u_char *curr, *prev = NULL; for (i = 0; i < dd->num_wds; i++) { int len; curr = dd->wd[i]->word; if (prev) /* look for prefix match with prev string */ len = prefixlen (prev, curr); else len = 0; fputc ((len << 4) + (curr[0] - len), f); fwrite (curr + len + 1, sizeof (u_char), curr[0] - len, f); prev = curr; } }
static u_long Write_data (FILE * f, DictData * dd, int lookback) { u_long mem_reqd; huff_data *hd; int i; u_long us = dd->num_wds; long *freqs; u_long huff_words_size[MAX_HUFFCODE_LEN + 1]; u_long lencounts[MAX_HUFFCODE_LEN + 1]; u_char *lastword[MAX_HUFFCODE_LEN + 1]; if (!(freqs = Xmalloc ((dd->num_wds) * sizeof (*freqs)))) FatalError (1, "Unable to allocate memory for freqs"); for (i = 0; i < dd->num_wds; i++) { freqs[i] = dd->wd[i]->freq; us += dd->wd[i]->word[0]; } if (!(hd = Generate_Huffman_Data (dd->num_wds, freqs, NULL, NULL))) FatalError (1, "Unable to allocate memory for huffman data"); Xfree (freqs), freqs = NULL; if (Write_Huffman_Data (f, hd) == -1) FatalError (1, "Unable to write huffman data"); fwrite (&us, sizeof (us), 1, f); /* Calculate the amount of memory that will be required to store the text for each different huffman code len. Every 1<<lookback words for each different codelen length will not be prefixed by previous strings. */ bzero ((char *) &huff_words_size, sizeof (huff_words_size)); bzero ((char *) &lencounts, sizeof (lencounts)); mem_reqd = 0; for (i = 0; i < dd->num_wds; i++) { int codelen = hd->clens[i]; u_char *word = dd->wd[i]->word; if (!codelen) FatalError (1, "The length of a code for a word was zero"); huff_words_size[codelen] += word[0] + 1; mem_reqd += word[0] + (lookback != 0); #if 0 if ((lencounts[codelen] & ((1 << lookback) - 1)) == 0) lastword[codelen] = word; else huff_words_size[codelen] -= prefixlen (lastword[codelen], word); #else if ((lencounts[codelen] & ((1 << lookback) - 1)) != 0) { int save = prefixlen (lastword[codelen], word); mem_reqd -= save; huff_words_size[codelen] -= save; } else { mem_reqd += sizeof (u_char *); } lastword[codelen] = word; #endif lencounts[codelen]++; } fwrite (huff_words_size + hd->mincodelen, sizeof (*huff_words_size), hd->maxcodelen - hd->mincodelen + 1, f); Write_words (f, dd); Xfree (hd->clens); Xfree (hd); return mem_reqd; }
void main(int argc, char **argv) { int p[2], pid, i, j, n, off, npad, prefix; char **av, *q, *r, *tofree, *name; char nambuf[100]; Biobuf *bin, *bout; Type *t; Field *f; quotefmtinstall(); oargc = argc; oargv = argv; av = emalloc((30+argc)*sizeof av[0]); atexit(waitforgcc); n = 0; av[n++] = "gcc"; av[n++] = "-c"; av[n++] = "-fdollars-in-identifiers"; av[n++] = "-S"; // write assembly av[n++] = "-gstabs"; // include stabs info av[n++] = "-o-"; // to stdout av[n++] = "-xc"; // read C ARGBEGIN{ case 'g': lang = &go; pkg = EARGF(usage()); break; case 'c': av[0] = EARGF(usage()); break; case 'f': av[n++] = EARGF(usage()); break; default: usage(); }ARGEND if(argc == 0) av[n++] = "-"; else av[n++] = argv[0]; av[n] = nil; // Run gcc writing assembly and stabs debugging to p[1]. if(pipe(p) < 0) sysfatal("pipe: %r"); pid = fork(); if(pid < 0) sysfatal("fork: %r"); if(pid == 0) { close(p[0]); dup(p[1], 1); if(argc == 0) { exec(av[0], av); fprint(2, "exec gcc: %r\n"); exit(1); } // Some versions of gcc do not accept -S with multiple files. // Run gcc once for each file. close(0); open("/dev/null", OREAD); for(i=0; i<argc; i++) { pid = fork(); if(pid < 0) sysfatal("fork: %r"); if(pid == 0) { av[n-1] = argv[i]; exec(av[0], av); fprint(2, "exec gcc: %r\n"); exit(1); } waitpid(); } exit(0); } close(p[1]); // Read assembly, pulling out .stabs lines. bin = Bfdopen(p[0], OREAD); while((q = Brdstr(bin, '\n', 1)) != nil) { // .stabs "float:t(0,12)=r(0,1);4;0;",128,0,0,0 tofree = q; while(*q == ' ' || *q == '\t') q++; if(strncmp(q, ".stabs", 6) != 0) goto Continue; q += 6; while(*q == ' ' || *q == '\t') q++; if(*q++ != '\"') { Bad: sysfatal("cannot parse .stabs line:\n%s", tofree); } r = strchr(q, '\"'); if(r == nil) goto Bad; *r++ = '\0'; if(*r++ != ',') goto Bad; if(*r < '0' || *r > '9') goto Bad; if(atoi(r) != 128) // stabs kind = local symbol goto Continue; parsestabtype(q); Continue: free(tofree); } Bterm(bin); waitpid(); // Write defs to standard output. bout = Bfdopen(1, OWRITE); fmtinstall('T', lang->typefmt); // Echo original command line in header. Bprint(bout, "//"); for(i=0; i<oargc; i++) Bprint(bout, " %q", oargv[i]); Bprint(bout, "\n"); Bprint(bout, "\n"); Bprint(bout, "// MACHINE GENERATED - DO NOT EDIT.\n"); Bprint(bout, "\n"); if(pkg) Bprint(bout, "package %s\n\n", pkg); // Constants. Bprint(bout, "// Constants\n"); if(ncon > 0) { Bprint(bout, lang->constbegin); for(i=0; i<ncon; i++) Bprint(bout, lang->constfmt, con[i].name, con[i].value); Bprint(bout, lang->constend); } Bprint(bout, "\n"); // Types // push our names down for(i=0; i<ntyp; i++) { t = typ[i]; name = t->name; while(t && t->kind == Typedef) t = t->type; if(t) t->name = name; } Bprint(bout, "// Types\n"); // Have to turn off structure padding in Plan 9 compiler, // mainly because it is more aggressive than gcc tends to be. if(lang == &c) Bprint(bout, "#pragma pack on\n"); for(i=0; i<ntyp; i++) { Bprint(bout, "\n"); t = typ[i]; name = t->name; while(t && t->kind == Typedef) { if(name == nil && t->name != nil) { name = t->name; if(t->printed) break; } t = t->type; } if(name == nil && t->name != nil) { name = t->name; if(t->printed) continue; t->printed = 1; } if(name == nil) { fprint(2, "unknown name for %T", typ[i]); continue; } if(name[0] == '$') name++; npad = 0; off = 0; switch(t->kind) { case 0: fprint(2, "unknown type definition for %s\n", name); break; default: // numeric, array, or pointer case Array: case Ptr: Bprint(bout, "%s %lT\n", lang->typdef, name, t); break; case Union: // In Go, print union as struct with only first element, // padded the rest of the way. Bprint(bout, lang->unionbegin, name, name, name); goto StructBody; case Struct: Bprint(bout, lang->structbegin, name, name, name); StructBody: prefix = 0; if(lang == &go) prefix = prefixlen(t); for(j=0; j<t->nf; j++) { f = &t->f[j]; // padding if(t->kind == Struct || lang == &go) { if(f->offset%8 != 0 || f->size%8 != 0) { fprint(2, "ignoring bitfield %s.%s\n", t->name, f->name); continue; } if(f->offset < off) sysfatal("%s: struct fields went backward", t->name); if(off < f->offset) { Bprint(bout, lang->structpadfmt, npad++, (f->offset - off) / 8); off = f->offset; } off += f->size; } name = f->name; if(cutprefix(name)) name += prefix; if(strcmp(name, "") == 0) { snprint(nambuf, sizeof nambuf, "Pad%d", npad++); name = nambuf; } Bprint(bout, "\t%#lT;\n", name, f->type); if(t->kind == Union && lang == &go) break; } // final padding if(t->kind == Struct || lang == &go) { if(off/8 < t->size) Bprint(bout, lang->structpadfmt, npad++, t->size - off/8); } Bprint(bout, lang->structend); } } if(lang == &c) Bprint(bout, "#pragma pack off\n"); Bterm(bout); exit(0); }