1*8ccd4a63SDavid du Colombier enum { 2*8ccd4a63SDavid du Colombier NbNameLen = 16, 3*8ccd4a63SDavid du Colombier NbnsTimeoutBroadcast = 1000, 4*8ccd4a63SDavid du Colombier NbnsRetryBroadcast = 3, 5*8ccd4a63SDavid du Colombier NbnsPort = 137, 6*8ccd4a63SDavid du Colombier NbDgramMaxLen = 576, 7*8ccd4a63SDavid du Colombier }; 8*8ccd4a63SDavid du Colombier 9*8ccd4a63SDavid du Colombier typedef struct NbnsHdr { 10*8ccd4a63SDavid du Colombier uchar name_trn_id[2]; 11*8ccd4a63SDavid du Colombier uchar ctrl[2]; 12*8ccd4a63SDavid du Colombier uchar qdcount[2]; 13*8ccd4a63SDavid du Colombier uchar ancount[2]; 14*8ccd4a63SDavid du Colombier uchar nscount[2]; 15*8ccd4a63SDavid du Colombier uchar arcount[2]; 16*8ccd4a63SDavid du Colombier } NbnsHdr; 17*8ccd4a63SDavid du Colombier 18*8ccd4a63SDavid du Colombier enum { 19*8ccd4a63SDavid du Colombier NbnsResponse = 1 << 15 20*8ccd4a63SDavid du Colombier }; 21*8ccd4a63SDavid du Colombier 22*8ccd4a63SDavid du Colombier enum { 23*8ccd4a63SDavid du Colombier NbnsOpShift = 11, 24*8ccd4a63SDavid du Colombier NbnsOpMask = 0xf, 25*8ccd4a63SDavid du Colombier NbnsOpQuery = 0, 26*8ccd4a63SDavid du Colombier NbnsOpRegistration = 5, 27*8ccd4a63SDavid du Colombier NbnsOpRelease = 6, 28*8ccd4a63SDavid du Colombier NbnsOpWack = 7, 29*8ccd4a63SDavid du Colombier NbnsOpRefresh = 8 30*8ccd4a63SDavid du Colombier }; 31*8ccd4a63SDavid du Colombier 32*8ccd4a63SDavid du Colombier enum { 33*8ccd4a63SDavid du Colombier NbnsFlagBroadcast = (1 << 4), 34*8ccd4a63SDavid du Colombier NbnsFlagRecursionAvailable = (1 << 7), 35*8ccd4a63SDavid du Colombier NbnsFlagRecursionDesired = (1 << 8), 36*8ccd4a63SDavid du Colombier NbnsFlagTruncation = (1 << 9), 37*8ccd4a63SDavid du Colombier NbnsFlagAuthoritativeAnswer = (1 << 10), 38*8ccd4a63SDavid du Colombier }; 39*8ccd4a63SDavid du Colombier 40*8ccd4a63SDavid du Colombier enum { 41*8ccd4a63SDavid du Colombier NbnsRcodeShift = 0, 42*8ccd4a63SDavid du Colombier NbnsRcodeMask = 0xf, 43*8ccd4a63SDavid du Colombier }; 44*8ccd4a63SDavid du Colombier 45*8ccd4a63SDavid du Colombier enum { 46*8ccd4a63SDavid du Colombier NbnsQuestionTypeNb = 0x0020, 47*8ccd4a63SDavid du Colombier NbnsQuestionTypeNbStat = 0x0021, 48*8ccd4a63SDavid du Colombier NbnsQuestionClassIn = 0x0001, 49*8ccd4a63SDavid du Colombier }; 50*8ccd4a63SDavid du Colombier 51*8ccd4a63SDavid du Colombier enum { 52*8ccd4a63SDavid du Colombier NbnsResourceTypeA = 0x0001, 53*8ccd4a63SDavid du Colombier NbnsResourceTypeNs = 0x0002, 54*8ccd4a63SDavid du Colombier NbnsResourceTypeNull = 0x000a, 55*8ccd4a63SDavid du Colombier NbnsResourceTypeNb = 0x0020, 56*8ccd4a63SDavid du Colombier NbnsResourceTypeNbStat = 0x0021, 57*8ccd4a63SDavid du Colombier NbnsResourceClassIn = 0x0001, 58*8ccd4a63SDavid du Colombier }; 59*8ccd4a63SDavid du Colombier 60*8ccd4a63SDavid du Colombier typedef struct NbnsMessageQuestion NbnsMessageQuestion; 61*8ccd4a63SDavid du Colombier typedef struct NbnsMessageResource NbnsMessageResource; 62*8ccd4a63SDavid du Colombier 63*8ccd4a63SDavid du Colombier typedef uchar NbName[NbNameLen]; 64*8ccd4a63SDavid du Colombier int nbnamedecode(uchar *base, uchar *p, uchar *ep, NbName name); 65*8ccd4a63SDavid du Colombier int nbnameencode(uchar *p, uchar *ep, NbName name); 66*8ccd4a63SDavid du Colombier int nbnameequal(NbName name1, NbName name2); 67*8ccd4a63SDavid du Colombier void nbnamecpy(NbName n1, NbName n2); 68*8ccd4a63SDavid du Colombier void nbmknamefromstring(NbName nbname, char *string); 69*8ccd4a63SDavid du Colombier void nbmknamefromstringandtype(NbName nbname, char *string, uchar type); 70*8ccd4a63SDavid du Colombier void nbmkstringfromname(char *buf, int buflen, NbName name); 71*8ccd4a63SDavid du Colombier #pragma varargck type "B" uchar * 72*8ccd4a63SDavid du Colombier 73*8ccd4a63SDavid du Colombier int nbnamefmt(Fmt *); 74*8ccd4a63SDavid du Colombier 75*8ccd4a63SDavid du Colombier struct NbnsMessageQuestion { 76*8ccd4a63SDavid du Colombier NbName name; 77*8ccd4a63SDavid du Colombier ushort type; 78*8ccd4a63SDavid du Colombier ushort class; 79*8ccd4a63SDavid du Colombier NbnsMessageQuestion *next; 80*8ccd4a63SDavid du Colombier }; 81*8ccd4a63SDavid du Colombier 82*8ccd4a63SDavid du Colombier NbnsMessageQuestion *nbnsmessagequestionnew(NbName name, ushort type, ushort class); 83*8ccd4a63SDavid du Colombier 84*8ccd4a63SDavid du Colombier struct NbnsMessageResource { 85*8ccd4a63SDavid du Colombier NbName name; 86*8ccd4a63SDavid du Colombier ushort type; 87*8ccd4a63SDavid du Colombier ushort class; 88*8ccd4a63SDavid du Colombier ulong ttl; 89*8ccd4a63SDavid du Colombier ushort rdlength; 90*8ccd4a63SDavid du Colombier uchar *rdata; 91*8ccd4a63SDavid du Colombier NbnsMessageResource *next; 92*8ccd4a63SDavid du Colombier }; 93*8ccd4a63SDavid du Colombier NbnsMessageResource *nbnsmessageresourcenew(NbName name, ushort type, ushort class, ulong ttl, int rdcount, uchar *rdata); 94*8ccd4a63SDavid du Colombier 95*8ccd4a63SDavid du Colombier typedef struct NbnsMessage { 96*8ccd4a63SDavid du Colombier ushort id; 97*8ccd4a63SDavid du Colombier int response; 98*8ccd4a63SDavid du Colombier int opcode; 99*8ccd4a63SDavid du Colombier int broadcast; 100*8ccd4a63SDavid du Colombier int recursionavailable; 101*8ccd4a63SDavid du Colombier int recursiondesired; 102*8ccd4a63SDavid du Colombier int truncation; 103*8ccd4a63SDavid du Colombier int authoritativeanswer; 104*8ccd4a63SDavid du Colombier int rcode; 105*8ccd4a63SDavid du Colombier NbnsMessageQuestion *q; 106*8ccd4a63SDavid du Colombier NbnsMessageResource *an; 107*8ccd4a63SDavid du Colombier NbnsMessageResource *ns; 108*8ccd4a63SDavid du Colombier NbnsMessageResource *ar; 109*8ccd4a63SDavid du Colombier } NbnsMessage; 110*8ccd4a63SDavid du Colombier 111*8ccd4a63SDavid du Colombier NbnsMessage *nbnsmessagenew(void); 112*8ccd4a63SDavid du Colombier void nbnsmessageaddquestion(NbnsMessage *s, NbnsMessageQuestion *q); 113*8ccd4a63SDavid du Colombier void nbnsmessageaddresource(NbnsMessageResource **rp, NbnsMessageResource *r); 114*8ccd4a63SDavid du Colombier NbnsMessage *nbnsconvM2S(uchar *ap, int nap); 115*8ccd4a63SDavid du Colombier void nbnsmessagefree(NbnsMessage **sp); 116*8ccd4a63SDavid du Colombier void nbnsdumpmessage(NbnsMessage *s); 117*8ccd4a63SDavid du Colombier int nbnsconvS2M(NbnsMessage *s, uchar *ap, int nap); 118*8ccd4a63SDavid du Colombier 119*8ccd4a63SDavid du Colombier 120*8ccd4a63SDavid du Colombier NbnsMessage *nbnsmessagenamequeryrequestnew(ushort id, int broadcast, NbName name); 121*8ccd4a63SDavid du Colombier NbnsMessage *nbnsmessagenameregistrationrequestnew(ushort id, int broadcast, NbName name, ulong ttl, uchar *ipaddr); 122*8ccd4a63SDavid du Colombier 123*8ccd4a63SDavid du Colombier typedef struct NbnsTransaction NbnsTransaction; 124*8ccd4a63SDavid du Colombier 125*8ccd4a63SDavid du Colombier struct NbnsTransaction { 126*8ccd4a63SDavid du Colombier ushort id; 127*8ccd4a63SDavid du Colombier Channel *c; 128*8ccd4a63SDavid du Colombier NbnsTransaction *next; 129*8ccd4a63SDavid du Colombier }; 130*8ccd4a63SDavid du Colombier ushort nbnsnextid(void); 131*8ccd4a63SDavid du Colombier 132*8ccd4a63SDavid du Colombier int nbnsfindname(uchar *serveripaddr, NbName name, uchar *ipaddr, ulong *ttlp); 133*8ccd4a63SDavid du Colombier int nbnsaddname(uchar *serveripaddr, NbName name, ulong ttl, uchar *ipaddr); 134*8ccd4a63SDavid du Colombier 135*8ccd4a63SDavid du Colombier NbnsTransaction *nbnstransactionnew(NbnsMessage *request, uchar *ipaddr); 136*8ccd4a63SDavid du Colombier void nbnstransactionfree(NbnsTransaction **tp); 137*8ccd4a63SDavid du Colombier 138*8ccd4a63SDavid du Colombier typedef struct NbnsAlarm NbnsAlarm; 139*8ccd4a63SDavid du Colombier 140*8ccd4a63SDavid du Colombier struct NbnsAlarm { 141*8ccd4a63SDavid du Colombier Channel *c; 142*8ccd4a63SDavid du Colombier vlong expirems; 143*8ccd4a63SDavid du Colombier NbnsAlarm *next; 144*8ccd4a63SDavid du Colombier }; 145*8ccd4a63SDavid du Colombier 146*8ccd4a63SDavid du Colombier void nbnsalarmset(NbnsAlarm *a, ulong millisec); 147*8ccd4a63SDavid du Colombier void nbnsalarmcancel(NbnsAlarm *a); 148*8ccd4a63SDavid du Colombier void nbnsalarmfree(NbnsAlarm **ap); 149*8ccd4a63SDavid du Colombier NbnsAlarm *nbnsalarmnew(void); 150*8ccd4a63SDavid du Colombier void nbnsalarmend(void); 151*8ccd4a63SDavid du Colombier 152*8ccd4a63SDavid du Colombier typedef struct NbSession NbSession; 153*8ccd4a63SDavid du Colombier typedef int NBSSWRITEFN(NbSession *s, void *buf, long n); 154*8ccd4a63SDavid du Colombier 155*8ccd4a63SDavid du Colombier struct NbSession { 156*8ccd4a63SDavid du Colombier int fd; 157*8ccd4a63SDavid du Colombier void *magic; 158*8ccd4a63SDavid du Colombier NbName from; 159*8ccd4a63SDavid du Colombier NbName to; 160*8ccd4a63SDavid du Colombier }; 161*8ccd4a63SDavid du Colombier 162*8ccd4a63SDavid du Colombier int nbsslisten(NbName to, NbName from, int (*accept)(void *magic, NbSession *s, NBSSWRITEFN **write), void *magic); 163*8ccd4a63SDavid du Colombier NbSession *nbssconnect(NbName to, NbName from); 164*8ccd4a63SDavid du Colombier void nbssfree(NbSession *s); 165*8ccd4a63SDavid du Colombier 166*8ccd4a63SDavid du Colombier typedef struct NbScatterGather NbScatterGather; 167*8ccd4a63SDavid du Colombier 168*8ccd4a63SDavid du Colombier struct NbScatterGather { 169*8ccd4a63SDavid du Colombier void *p; 170*8ccd4a63SDavid du Colombier long l; 171*8ccd4a63SDavid du Colombier }; 172*8ccd4a63SDavid du Colombier 173*8ccd4a63SDavid du Colombier int nbssgatherwrite(NbSession *s, NbScatterGather *a); 174*8ccd4a63SDavid du Colombier long nbssscatterread(NbSession *, NbScatterGather *a); 175*8ccd4a63SDavid du Colombier int nbsswrite(NbSession *s, void *buf, long n); 176*8ccd4a63SDavid du Colombier long nbssread(NbSession *s, void *buf, long n); 177*8ccd4a63SDavid du Colombier void *nbemalloc(ulong); 178*8ccd4a63SDavid du Colombier 179*8ccd4a63SDavid du Colombier int nbnameresolve(NbName name, uchar *ipaddr); 180*8ccd4a63SDavid du Colombier 181*8ccd4a63SDavid du Colombier void nbdumpdata(void *data, long datalen); 182*8ccd4a63SDavid du Colombier 183*8ccd4a63SDavid du Colombier typedef struct NbDgram { 184*8ccd4a63SDavid du Colombier uchar type; 185*8ccd4a63SDavid du Colombier uchar flags; 186*8ccd4a63SDavid du Colombier ushort id; 187*8ccd4a63SDavid du Colombier uchar srcip[IPaddrlen]; 188*8ccd4a63SDavid du Colombier ushort srcport; 189*8ccd4a63SDavid du Colombier union { 190*8ccd4a63SDavid du Colombier struct { 191*8ccd4a63SDavid du Colombier ushort length; 192*8ccd4a63SDavid du Colombier ushort offset; 193*8ccd4a63SDavid du Colombier NbName srcname; 194*8ccd4a63SDavid du Colombier NbName dstname; 195*8ccd4a63SDavid du Colombier uchar *data; 196*8ccd4a63SDavid du Colombier } datagram; 197*8ccd4a63SDavid du Colombier struct { 198*8ccd4a63SDavid du Colombier uchar code; 199*8ccd4a63SDavid du Colombier } error; 200*8ccd4a63SDavid du Colombier struct { 201*8ccd4a63SDavid du Colombier NbName dstname; 202*8ccd4a63SDavid du Colombier } query; 203*8ccd4a63SDavid du Colombier }; 204*8ccd4a63SDavid du Colombier } NbDgram; 205*8ccd4a63SDavid du Colombier 206*8ccd4a63SDavid du Colombier enum { 207*8ccd4a63SDavid du Colombier NbDgramDirectUnique = 0x10, 208*8ccd4a63SDavid du Colombier NbDgramDirectGroup, 209*8ccd4a63SDavid du Colombier NbDgramBroadcast, 210*8ccd4a63SDavid du Colombier NbDgramError, 211*8ccd4a63SDavid du Colombier NbDgramQueryRequest, 212*8ccd4a63SDavid du Colombier NbDgramPositiveQueryResponse, 213*8ccd4a63SDavid du Colombier NbDgramNegativeQueryResponse, 214*8ccd4a63SDavid du Colombier NbDgramMore = 1, 215*8ccd4a63SDavid du Colombier NbDgramFirst = 2, 216*8ccd4a63SDavid du Colombier NbDgramPort = 138, 217*8ccd4a63SDavid du Colombier NbDgramErrorDestinationNameNotPresent = 0x82, 218*8ccd4a63SDavid du Colombier NbDgramMaxPacket = 576, 219*8ccd4a63SDavid du Colombier }; 220*8ccd4a63SDavid du Colombier 221*8ccd4a63SDavid du Colombier typedef struct NbDgramSendParameters { 222*8ccd4a63SDavid du Colombier NbName to; 223*8ccd4a63SDavid du Colombier uchar type; 224*8ccd4a63SDavid du Colombier } NbDgramSendParameters; 225*8ccd4a63SDavid du Colombier 226*8ccd4a63SDavid du Colombier int nbdgramconvM2S(NbDgram *s, uchar *p, uchar *ep); 227*8ccd4a63SDavid du Colombier int nbdgramconvS2M(uchar *p, uchar *ep, NbDgram *s); 228*8ccd4a63SDavid du Colombier void nbdgramdump(NbDgram *s); 229*8ccd4a63SDavid du Colombier int nbdgramsendto(uchar *ipaddr, ushort port, NbDgram *s); 230*8ccd4a63SDavid du Colombier int nbdgramsend(NbDgramSendParameters *p, unsigned char *data, long datalen); 231*8ccd4a63SDavid du Colombier char *nbdgramlisten(NbName to, int (*deliver)(void *magic, NbDgram *s), void *magic); 232*8ccd4a63SDavid du Colombier 233*8ccd4a63SDavid du Colombier int nbnametablefind(NbName name, int add); 234*8ccd4a63SDavid du Colombier int nbnameisany(NbName name); 235*8ccd4a63SDavid du Colombier 236*8ccd4a63SDavid du Colombier int nbremotenametablefind(NbName name, uchar *ipaddr); 237*8ccd4a63SDavid du Colombier int nbremotenametableadd(NbName name, uchar *ipaddr, ulong ttl); 238*8ccd4a63SDavid du Colombier 239*8ccd4a63SDavid du Colombier typedef struct NbGlobals { 240*8ccd4a63SDavid du Colombier uchar myipaddr[IPaddrlen]; 241*8ccd4a63SDavid du Colombier uchar bcastaddr[IPaddrlen]; 242*8ccd4a63SDavid du Colombier NbName myname; 243*8ccd4a63SDavid du Colombier } NbGlobals; 244*8ccd4a63SDavid du Colombier 245*8ccd4a63SDavid du Colombier extern NbGlobals nbglobals; 246*8ccd4a63SDavid du Colombier extern NbName nbnameany; 247*8ccd4a63SDavid du Colombier 248*8ccd4a63SDavid du Colombier int nbinit(void); 249*8ccd4a63SDavid du Colombier char *nbudpannounce(ushort port, int *fdp); 250*8ccd4a63SDavid du Colombier 251*8ccd4a63SDavid du Colombier extern int nbudphdrsize; 252