static void store_route(struct rt_msghdr *rtm) { u_int i; struct natm_route *r; char *cp; struct sockaddr *sa; struct sockaddr_in *sain; struct sockaddr_dl *sdl; struct diagif *aif; u_int n; r = malloc(sizeof(*r)); if (r == NULL) err(1, "allocate route"); r->flags = rtm->rtm_flags; cp = (char *)(rtm + 1); for (i = 1; i != 0; i <<= 1) { if (rtm->rtm_addrs & i) { sa = (struct sockaddr *)cp; cp += roundup(sa->sa_len, sizeof(long)); switch (i) { case RTA_DST: if (sa->sa_family != AF_INET) { warnx("RTA_DST not AF_INET %u", sa->sa_family); goto fail; } sain = (struct sockaddr_in *)(void *)sa; if (sain->sin_len < 4) r->host.s_addr = INADDR_ANY; else r->host = sain->sin_addr; break; case RTA_GATEWAY: if (sa->sa_family != AF_LINK) { warnx("RTA_GATEWAY not AF_LINK"); goto fail; } sdl = (struct sockaddr_dl *)(void *)sa; TAILQ_FOREACH(aif, &diagif_list, link) if (strlen(aif->ifname) == sdl->sdl_nlen && strncmp(aif->ifname, sdl->sdl_data, sdl->sdl_nlen) == 0) break; if (aif == NULL) { warnx("interface '%.*s' not found", sdl->sdl_nlen, sdl->sdl_data); goto fail; } r->aif = aif; /* parse ATM stuff */ #define GET3() (((sdl->sdl_data[n] & 0xff) << 16) | \ ((sdl->sdl_data[n + 1] & 0xff) << 8) | \ ((sdl->sdl_data[n + 2] & 0xff) << 0)) #define GET2() (((sdl->sdl_data[n] & 0xff) << 8) | \ ((sdl->sdl_data[n + 1] & 0xff) << 0)) #define GET1() (((sdl->sdl_data[n] & 0xff) << 0)) n = sdl->sdl_nlen; if (sdl->sdl_alen < 4) { warnx("RTA_GATEWAY alen too short"); goto fail; } r->llcsnap = GET1() & ATM_PH_LLCSNAP; n++; r->vpi = GET1(); n++; r->vci = GET2(); n += 2; if (sdl->sdl_alen == 4) { /* old address */ r->traffic = ATMIO_TRAFFIC_UBR; r->pcr = 0; break; } /* new address */ r->traffic = GET1(); n++; switch (r->traffic) { case ATMIO_TRAFFIC_UBR: if (sdl->sdl_alen >= 5 + 3) { r->pcr = GET3(); n += 3; } else r->pcr = 0; break; case ATMIO_TRAFFIC_CBR: if (sdl->sdl_alen < 5 + 3) { warnx("CBR address too short"); goto fail; } r->pcr = GET3(); n += 3; break; case ATMIO_TRAFFIC_VBR: if (sdl->sdl_alen < 5 + 3 * 3) { warnx("VBR address too short"); goto fail; } r->pcr = GET3(); n += 3; r->scr = GET3(); n += 3; r->mbs = GET3(); n += 3; break; case ATMIO_TRAFFIC_ABR: if (sdl->sdl_alen < 5 + 4 * 3 + 2 + 1 * 2 + 3) { warnx("ABR address too short"); goto fail; } r->pcr = GET3(); n += 3; r->mcr = GET3(); n += 3; r->icr = GET3(); n += 3; r->tbe = GET3(); n += 3; r->nrm = GET1(); n++; r->trm = GET1(); n++; r->adtf = GET2(); n += 2; r->rif = GET1(); n++; r->rdf = GET1(); n++; r->cdf = GET1(); n++; break; default: goto fail; } break; } } }
doc to_doc(char *s) { int a[9]; doc ret; memset(&ret, 0, sizeof(ret)); while (*s) switch (*s) { case 'l': GET1(a[0] >= 1 && a[0] <= 1000, new_line(&ret, ret.size, a[0])); EOL; break; case 'i': GET0(ret.size >= 1, new_item(&ret.l[ret.size-1], ret.l[ret.size-1].size)); EOL; break; case 'c': GET3(ret.size >= 1 && ret.l[ret.size-1].size >= 1 && a[0] >= CLEF_SOL && a[0] <= CLEF_DO && a[1] >= 0 && a[1] < ret.l[ret.size-1].n && a[2] >= -100 && a[2] <= 100, new_vertical_item(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], ret.l[ret.size-1].i[ret.l[ret.size-1].size-1].size, CLEF, a[0], a[1], a[2])); EOL; break; case 'a': GET3(ret.size >= 1 && ret.l[ret.size-1].size >= 1 && (a[0] == DIESE || a[0] == BEMOL) && a[1] >= 0 && a[1] < ret.l[ret.size-1].n && a[2] >= -100 && a[2] <= 100, new_vertical_item(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], ret.l[ret.size-1].i[ret.l[ret.size-1].size-1].size, ARMATURE, a[0], a[1], a[2])); EOL; break; case 'n': GET9(ret.size >= 1 && ret.l[ret.size-1].size >= 1 && a[0] >= 0 && a[0] <= 16 && a[1] >= 0 && a[1] <= 4 && a[2] >= NO_ALTERATION && a[2] <= BECARRE && a[3] >= 0 && a[3] < ret.l[ret.size-1].n && a[4] >= -100 && a[4] <= 100 && a[5] >= STEM_UP && a[5] <= STEM_NONE /* l, m, o may be whatever, no check */, new_vertical_item(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], ret.l[ret.size-1].i[ret.l[ret.size-1].size-1].size, NOTE, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])); EOL; break; case 's': GET4(ret.size >= 1 && ret.l[ret.size-1].size >= 1 && a[0] >= 0 && a[0] <= 16 && a[1] >= 0 && a[1] <= 4 && a[2] >= 0 && a[2] < ret.l[ret.size-1].n && a[3] >= -100 && a[3] <= 100, new_vertical_item(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], ret.l[ret.size-1].i[ret.l[ret.size-1].size-1].size, SILENCE, a[0], a[1], a[2], a[3])); EOL; break; case 'b': GET0(ret.size >= 1 && ret.l[ret.size-1].size >= 1, new_vertical_item(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], ret.l[ret.size-1].i[ret.l[ret.size-1].size-1].size, BAR)); EOL; break; case 't': GET3(ret.size >= 1 && ret.l[ret.size-1].size >= 1 && a[2] > 0, do { int tlen; char *t = malloc(a[2]+1); if (t == NULL) abort(); s++; /* not pretty */ while (*s && *s != ' ') s++; if (*s == ' ') s++; while (*s && *s != ' ') s++; if (*s == ' ') s++; while (*s && *s != ' ') s++; if (*s == ' ') s++; while (*s && *s != ' ') s++; if (*s == ' ') s++; for (tlen = 0; *s && tlen < a[2]; tlen++, s++) t[tlen] = *s; t[tlen] = 0; new_text(&ret.l[ret.size-1].i[ret.l[ret.size-1].size-1], t, a[0], a[1]); free(t); } while (0)); EOL; break; case '#': EOL; break; /* why not deal with comments? only 1 line of code! */ default: printf("error in string to doc, ignoring a line\n"); EOL; break; } return ret; }