static void ethernetprotocol_notify(struct ethernet_header *ethernetheader, void *buffer, unsigned int count) { union event_message message; struct arp_header *header = buffer; unsigned char *data = (unsigned char *)(header + 1); unsigned int htype = (header->htype[0] << 8) | header->htype[1]; unsigned int ptype = (header->ptype[0] << 8) | header->ptype[1]; unsigned int operation = (header->operation[0] << 8) | header->operation[1]; unsigned char *sha = data; unsigned char *spa = data + header->hlength; unsigned char *tha = data + header->hlength + header->plength; unsigned char *tpa = data + header->hlength + header->plength + header->hlength; struct arp_hook *hook = findhook(htype, header->hlength, ptype, header->plength); if (hook) { switch (operation) { case ARP_REQUEST: hook->save(sha, spa); tha = hook->lookup(tpa); if (tha) { unsigned char response[ETHERNET_MTU]; unsigned char *current = arp_writehead(response, htype, header->hlength, ptype, header->plength, ARP_REPLY, tha, tpa, sha, spa); ethernet_send(response, current - response); } break; case ARP_REPLY: hook->save(sha, spa); break; } } event_create(&message, EVENT_DATA); event_append(&message, count, buffer); kernel_multicast(EVENT_BROADCAST, ðernetprotocol.data.states, &message); }
/* This is a bit long and should probably be refactored a bit. */ enum parser_error parser_parse(struct parser *p, const char *line) { char *cline; char *tok; struct parser_hook *h; struct parser_spec *s; struct parser_value *v; char *sp = NULL; assert(p); assert(line); parser_freeold(p); p->lineno++; p->colno = 1; p->fhead = NULL; p->ftail = NULL; /* Ignore empty lines and comments. */ while (*line && (isspace(*line))) line++; if (!*line || *line == '#') return PARSE_ERROR_NONE; cline = string_make(line); tok = strtok(cline, ":"); if (!tok) { mem_free(cline); p->error = PARSE_ERROR_MISSING_FIELD; return PARSE_ERROR_MISSING_FIELD; } h = findhook(p, tok); if (!h) { my_strcpy(p->errmsg, tok, sizeof(p->errmsg)); p->error = PARSE_ERROR_UNDEFINED_DIRECTIVE; mem_free(cline); return PARSE_ERROR_UNDEFINED_DIRECTIVE; } /* There's a little bit of trickiness here to account for optional * types. The optional flag has a bit assigned to it in the spec's type * tag; we compute a temporary type for the spec with that flag removed * and use that instead. */ for (s = h->fhead; s; s = s->next) { int t = s->type & ~T_OPT; p->colno++; /* These types are tokenized on ':'; strings are not tokenized * at all (i.e., they consume the remainder of the line) */ if (t == T_INT || t == T_SYM || t == T_RAND || t == T_UINT) { tok = strtok(sp, ":"); sp = NULL; } else if (t == T_CHAR) { tok = strtok(sp, ""); if (tok) sp = tok + 2; } else { tok = strtok(sp, ""); sp = NULL; } if (!tok) { if (!(s->type & T_OPT)) { my_strcpy(p->errmsg, s->name, sizeof(p->errmsg)); p->error = PARSE_ERROR_MISSING_FIELD; mem_free(cline); return PARSE_ERROR_MISSING_FIELD; } break; } /* Allocate a value node, parse out its value, and link it into * the value list. */ v = mem_alloc(sizeof *v); v->spec.next = NULL; v->spec.type = s->type; v->spec.name = s->name; if (t == T_INT) { char *z = NULL; v->u.ival = strtol(tok, &z, 0); if (z == tok) { mem_free(v); mem_free(cline); my_strcpy(p->errmsg, s->name, sizeof(p->errmsg)); p->error = PARSE_ERROR_NOT_NUMBER; return PARSE_ERROR_NOT_NUMBER; } } else if (t == T_UINT) { char *z = NULL; v->u.uval = strtoul(tok, &z, 0); if (z == tok || *tok == '-') { mem_free(v); mem_free(cline); my_strcpy(p->errmsg, s->name, sizeof(p->errmsg)); p->error = PARSE_ERROR_NOT_NUMBER; return PARSE_ERROR_NOT_NUMBER; } } else if (t == T_CHAR) { v->u.cval = *tok; } else if (t == T_SYM || t == T_STR) { v->u.sval = string_make(tok); } else if (t == T_RAND) { if (!parse_random(tok, &v->u.rval)) { mem_free(v); mem_free(cline); my_strcpy(p->errmsg, s->name, sizeof(p->errmsg)); p->error = PARSE_ERROR_NOT_RANDOM; return PARSE_ERROR_NOT_RANDOM; } } if (!p->fhead) p->fhead = v; else p->ftail->spec.next = &v->spec; p->ftail = v; } mem_free(cline); p->error = h->func(p); return p->error; }