int ipsec_get_policylen(ipsec_policy_t policy) { u_int16_t aligned_len; if (policy) { memcpy(&aligned_len, policy, sizeof(u_int16_t)); return PFKEY_UNUNIT64(aligned_len); } else return -1; }
static int fileproc(const char *filename) { int fd; ssize_t len, l; u_char *p, *ep; struct sadb_msg *msg; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ fd = open(filename, O_RDONLY); if (fd < 0) return -1; l = 0; while (1) { len = read(fd, rbuf + l, sizeof(rbuf) - l); if (len < 0) { close(fd); return -1; } else if (len == 0) break; l += len; } if (l < sizeof(struct sadb_msg)) { close(fd); errno = EINVAL; return -1; } close(fd); p = rbuf; ep = rbuf + l; while (p < ep) { msg = (struct sadb_msg *)p; len = PFKEY_UNUNIT64(msg->sadb_msg_len); if (f_verbose) { kdebug_sadb((struct sadb_msg *)msg); printf("\n"); } postproc(msg, len); p += len; } return 0; }
key_output(struct mbuf *m, va_alist) #endif { struct sadb_msg *msg; int len, error = 0; int s; struct socket *so; va_list ap; va_start(ap, m); so = va_arg(ap, struct socket *); va_end(ap); if (m == 0) panic("key_output: NULL pointer was passed."); pfkeystat.out_total++; pfkeystat.out_bytes += m->m_pkthdr.len; len = m->m_pkthdr.len; if (len < sizeof(struct sadb_msg)) { pfkeystat.out_tooshort++; error = EINVAL; goto end; } if (m->m_len < sizeof(struct sadb_msg)) { if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) { pfkeystat.out_nomem++; error = ENOBUFS; goto end; } } if ((m->m_flags & M_PKTHDR) == 0) panic("key_output: not M_PKTHDR ??"); KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m)); msg = mtod(m, struct sadb_msg *); pfkeystat.out_msgtype[msg->sadb_msg_type]++; if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { pfkeystat.out_invlen++; error = EINVAL; goto end; } /*XXX giant lock*/ #ifdef __NetBSD__ s = splsoftnet(); #else s = splnet(); #endif error = key_parse(m, so); m = NULL; splx(s); end: if (m) m_freem(m); return error; }
int sendkeymsg(char *buf, size_t len) { u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ ssize_t l; struct sadb_msg *msg; if (f_notreally) { goto end; } { struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt"); goto end; } } if (f_forever) shortdump_hdr(); again: if (f_verbose) { kdebug_sadb((struct sadb_msg *)buf); printf("\n"); } if (f_hexdump) { int i; for (i = 0; i < len; i++) { if (i % 16 == 0) printf("%08x: ", i); printf("%02x ", buf[i] & 0xff); if (i % 16 == 15) printf("\n"); } if (len % 16) printf("\n"); } if ((l = send(so, buf, len, 0)) < 0) { perror("send"); goto end; } msg = (struct sadb_msg *)rbuf; do { if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); goto end; } if (PFKEY_UNUNIT64(msg->sadb_msg_len) != l) { warnx("invalid keymsg length"); break; } if (f_verbose) { kdebug_sadb(msg); printf("\n"); } if (postproc(msg, l) < 0) break; } while (msg->sadb_msg_errno || msg->sadb_msg_seq); if (f_forever) { fflush(stdout); sleep(1); goto again; } end: return 0; }
/* * Generate 'spi' array with SPIs matching 'satype', 'srcs', and 'dsts'. * Return value is dynamically generated array of SPIs, also number of * SPIs through num_spi pointer. * On any error, set *num_spi to 0 and return NULL. */ uint32_t * sendkeymsg_spigrep(unsigned int satype, struct addrinfo *srcs, struct addrinfo *dsts, int *num_spi) { struct sadb_msg msg, *m; char *buf; size_t len; ssize_t l; u_char rbuf[1024 * 32]; caddr_t mhp[SADB_EXT_MAX + 1]; struct sadb_address *saddr; struct sockaddr *s; struct addrinfo *a; struct sadb_sa *sa; uint32_t *spi = NULL; int max_spi = 0, fail = 0; *num_spi = 0; if (f_notreally) { return NULL; } { struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt"); return NULL; } } msg.sadb_msg_version = PF_KEY_V2; msg.sadb_msg_type = SADB_DUMP; msg.sadb_msg_errno = 0; msg.sadb_msg_satype = satype; msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); msg.sadb_msg_reserved = 0; msg.sadb_msg_seq = 0; msg.sadb_msg_pid = getpid(); buf = (char *)&msg; len = sizeof(msg); if (f_verbose) { kdebug_sadb(&msg); printf("\n"); } if (f_hexdump) { int i; for (i = 0; i < len; i++) { if (i % 16 == 0) printf("%08x: ", i); printf("%02x ", buf[i] & 0xff); if (i % 16 == 15) printf("\n"); } if (len % 16) printf("\n"); } if ((l = send(so, buf, len, 0)) < 0) { perror("send"); return NULL; } m = (struct sadb_msg *)rbuf; do { if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) { perror("recv"); fail = 1; break; } if (PFKEY_UNUNIT64(m->sadb_msg_len) != l) { warnx("invalid keymsg length"); fail = 1; break; } if (f_verbose) { kdebug_sadb(m); printf("\n"); } if (m->sadb_msg_type != SADB_DUMP) { warnx("unexpected message type"); fail = 1; break; } if (m->sadb_msg_errno != 0) { warnx("error encountered"); fail = 1; break; } /* match satype */ if (m->sadb_msg_satype != satype) continue; pfkey_align(m, mhp); pfkey_check(mhp); /* match src */ saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; if (saddr == NULL) continue; s = (struct sockaddr *)(saddr + 1); for (a = srcs; a; a = a->ai_next) if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0) break; if (a == NULL) continue; /* match dst */ saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]; if (saddr == NULL) continue; s = (struct sockaddr *)(saddr + 1); for (a = dsts; a; a = a->ai_next) if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0) break; if (a == NULL) continue; if (*num_spi >= max_spi) { max_spi += 512; spi = realloc(spi, max_spi * sizeof(uint32_t)); } sa = (struct sadb_sa *)mhp[SADB_EXT_SA]; if (sa != NULL) spi[(*num_spi)++] = (uint32_t)ntohl(sa->sadb_sa_spi); m = (struct sadb_msg *)((caddr_t)m + PFKEY_UNUNIT64(m->sadb_msg_len)); if (f_verbose) { kdebug_sadb(m); printf("\n"); } } while (m->sadb_msg_seq); if (fail) { free(spi); *num_spi = 0; return NULL; } return spi; }
static void __dead promisc(void) { struct sadb_msg msg; u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */ ssize_t l; msg.sadb_msg_version = PF_KEY_V2; msg.sadb_msg_type = SADB_X_PROMISC; msg.sadb_msg_errno = 0; msg.sadb_msg_satype = 1; msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg)); msg.sadb_msg_reserved = 0; msg.sadb_msg_seq = 0; msg.sadb_msg_pid = getpid(); if ((l = send(so, &msg, sizeof(msg), 0)) < 0) { err(1, "send"); } while (1) { struct sadb_msg *base; if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) { err(1, "recv"); } if (l != sizeof(*base)) continue; base = (struct sadb_msg *)rbuf; if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len), 0)) < 0) { err(1, "recv"); } printdate(); if (f_hexdump) { int i; for (i = 0; i < l; i++) { if (i % 16 == 0) printf("%08x: ", i); printf("%02x ", rbuf[i] & 0xff); if (i % 16 == 15) printf("\n"); } if (l % 16) printf("\n"); } /* adjust base pointer for promisc mode */ if (base->sadb_msg_type == SADB_X_PROMISC) { if ((ssize_t)sizeof(*base) < l) base++; else base = NULL; } if (base) { kdebug_sadb(base); printf("\n"); fflush(stdout); } } }