/* * The client for performing SLP registration/discovery, called by dotsd.c * * (c) Columbia University, 2004-2006, All Rights Reserved. * Author: Weibin Zhao */ #include "mod_dots.h" #define SLP_OFLOW_FLAG 0x8000 #define SLP_FRESH_FLAG 0x4000 #define SLP_MCAST_FLAG 0x2000 #define SLP_NORMAL_FLAG 0x0000 #define SLP_HEADER_LEN 12 #define SLP_VERSION 2 #define SLP_EndOfExt 0 #define SLP_SrvRqst 1 #define SLP_SrvRply 2 #define SLP_SrvReg 3 #define SLP_SrvAck 5 #define SLP_AttrListExt 0x0002 #define SLP_MeshFwdExt 0x0006 #define SLP_RqstFwd 1 #define SLP_Fwded 2 #define SLP_SelectExt 0x4002 #define SLP_SortExt 0x4003 #define SLP_LangTag "en" #define SLP_PR "" #define SLP_SPI "" #define SLP_DotsType "dotslash" #define SLP_DotsScope "dotslash" #define MAXBUF 4096 typedef struct { int ver; int fid; int len; int flag; int neo; int xid; int tlen; char tag[MAXNAME]; } slp_header_t; typedef struct { char url[MAXNAME]; int lifetime; } slp_url_t; /*----------------------------------------------- * Some basic functions for writing SLP messages *-----------------------------------------------*/ /* * Write SLP header to (*buf), without language tag * Thus, the length is fixed as 12 */ int slp_write_header(char **buf, int fid, int len, int flag, int xid) { write_int(&(*buf), SLP_VERSION, 1); write_int(&(*buf), fid, 1); write_int(&(*buf), len, 3); write_int(&(*buf), flag, 2); write_int(&(*buf), 0, 3); /* neo */ write_int(&(*buf), xid, 2); return SLP_HEADER_LEN; } /* * Write the correct packet lenght in SLP header */ void slp_write_hlen(char *buf, int len) { char *p = buf+2; write_int(&p, len, 3); // set len in SLP header } /* * Adjust SLP message for adding an extension, added length is "alen" * (1) last extension's NEO links to new extension * (2) adjust packet length: plen += alen */ void slp_adjust_mesg(char *buf, int alen) { char *p; int plen, next_ext, last_ext_offset; p = buf + 2; plen = read_int(&p, 3); // get existing packet len p = buf + 7; next_ext = read_int(&p, 3); // read neo in header last_ext_offset = 7; while (next_ext != SLP_EndOfExt) { last_ext_offset = next_ext + 2; p = buf + last_ext_offset; next_ext = read_int(&p, 3); } p = buf + last_ext_offset; write_int(&p, plen, 3); // link new extension p = buf + 2; write_int(&p, plen+alen, 3); // adjust message length } /* * Write a string to SLP message, the string is prefixed * by a short (16-bit) integer as its length * If the string is "", then only lenght zero is written */ int slp_write_string(char **buf, char *s) { int len; if (s == NULL) return 0; len = strlen(s); write_int(&(*buf), len, 2); memcpy(*buf, s, len); *buf += len; return (2+len); } /* * Write a URL entry to SLP message */ int slp_write_url(char **buf, char *url, int lifetime) { int len; write_int(&(*buf), 0, 1); // reserved write_int(&(*buf), lifetime, 2); // lifetime len = strlen(url); write_int(&(*buf), len, 2); // len of url memcpy(*buf, url, len); // copy url *buf += len; write_int(&(*buf), 0, 1); // num of auths return (6+len); } /*------------------ Write different SLP messages -----------------*/ /* * Write an SLP SrvRqst message into buf * Return: the message length in "buf" */ int slp_write_SrvRqst(char *buf, int xid, int flag, char *ltag, char *pr, char *type, char *scope, char *pred, char *spi) { char *p = buf; int len = 0; len += slp_write_header(&p, SLP_SrvRqst, 0, flag, xid); // set len later len += slp_write_string(&p, ltag); len += slp_write_string(&p, pr); len += slp_write_string(&p, type); len += slp_write_string(&p, scope); len += slp_write_string(&p, pred); len += slp_write_string(&p, spi); slp_write_hlen(buf, len); // set len now return len; } /* * Write an SLP SrvRply message into buf * Return: the message length in "buf" */ int slp_write_SrvRply(char *buf, int xid, int flag, char *ltag, int ecode, int count, slp_url_t *url_list) { char *p = buf; int i, len = 0; len += slp_write_header(&p, SLP_SrvRply, 0, flag, xid); // set len later len += slp_write_string(&p, ltag); len += write_int(&p, ecode, 2); len += write_int(&p, count, 2); for (i=0; iver = read_int(&(*buf), 1); h->fid = read_int(&(*buf), 1); h->len = read_int(&(*buf), 3); h->flag = read_int(&(*buf), 2); h->neo = read_int(&(*buf), 3); h->xid = read_int(&(*buf), 2); h->tlen = read_int(&(*buf), 2); memcpy(h->tag, *buf, h->tlen); h->tag[h->tlen] = '\0'; // as a string *buf += h->tlen; /* printf("ver=%d\n", h->ver); printf("fid=%d\n", h->fid); printf("len=%d\n", h->len); printf("flag=%x\n", h->flag); printf("neo=%d\n", h->neo); printf("xid=%d\n", h->xid); printf("tlen=%d\n", h->tlen); printf("tag=%s\n", h->tag); */ } /* * Read a string from SLP message */ void slp_read_string(char **buf, char *s) { int len = read_int(&(*buf), 2); s[0] = '\0'; // default is empty string if (len == 0xFFFF) strcpy(s, "*"); else if (len > 0) { memcpy(s, *buf, len); s[len] = '\0'; // as a string *buf += len; } } /* * Read a URL entry from SLP message */ void slp_read_url(char **buf, char *url, int *lifetime) { int dummy, len; dummy = read_int(&(*buf), 1); // reserved *lifetime = read_int(&(*buf), 2); len = read_int(&(*buf), 2); memcpy(url, *buf, len); url[len] = '\0'; // as a string *buf += len; dummy = read_int(&(*buf), 1); // num of auths } /*-------------------- Read different SLP messages -------------------*/ void slp_read_SrvRqst(char **buf) { char pr[MAXNAME], type[MAXNAME], scope[MAXNAME]; char pred[MAXNAME], spi[MAXNAME]; slp_read_string(&(*buf), pr); slp_read_string(&(*buf), type); slp_read_string(&(*buf), scope); slp_read_string(&(*buf), pred); slp_read_string(&(*buf), spi); /* printf("pr=%s\n", pr); printf("type=%s\n", type); printf("scope=%s\n", scope); printf("pred=%s\n", pred); printf("spi=%s\n", spi); */ } void slp_read_SrvRply(char **buf) { int i, ecode, count, lifetime; char url[MAXNAME]; ecode = read_int(&(*buf), 2); count = read_int(&(*buf), 2); /* fprintf(stderr, "ecode=%d, count=%d\n", ecode, count); */ for (i=0; i=%d)(CpuRate>=%4.2f)", min_link, min_cpu); len = slp_write_SrvRqst(buf, 1, SLP_NORMAL_FLAG, SLP_LangTag, SLP_PR, SLP_DotsType, SLP_DotsScope, attr, SLP_SPI); len = slp_write_SortExt(buf, sort_key); len = slp_write_SelectExt(buf, 20); len = slp_write_AttrListExt(buf, "", ""); network_sendrecv(buf, len); }