/*
* Netbios is big endian (network byte order),
* however SMB/CIFS is little endian (sigh)
*/
#include <u.h>
#include <libc.h>
#include <ip.h>
#include "nbcache.h"
Pkt *
allocpkt(int size)
{
Pkt *p;
p = mallocz(size+sizeof(Pkt), 1);
p->size = size;
p->buf = (uchar *)p + sizeof(Pkt);
p->up = (Udphdr *)p->buf;
p->pos = p->buf;
p->end = p->buf + p->size;
return p;
}
void
readpkt(int fd, Pkt *p)
{
int n;
if((n = read(fd, p->buf, p->size)) < 0)
sysfatal("net read failed - %r\n");
p->pos = p->buf + sizeof(Udphdr);
p->end = p->buf + n;
}
void
w8(Pkt *p, int n)
{
if(p->end - p->pos < 1){
fprint(2, "w8() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 1);
longjmp(p->err, 1);
}
*p->pos++ = n;
}
int
r8(Pkt *p)
{
int n;
if(p->end - p->pos < 1){
fprint(2, "r8() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 1);
longjmp(p->err, 1);
}
n = *p->pos++;
return n;
}
int
rl16(Pkt *p)
{
int n;
if(p->end - p->pos < 2){
fprint(2, "r16() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 2);
longjmp(p->err, 1);
}
n = *p->pos++;
n |= (*p->pos++) << 8;
return n;
}
void
wl16(Pkt *p, int n)
{
if(p->end - p->pos < 2){
fprint(2, "wl16() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 2);
longjmp(p->err, 1);
}
*p->pos++ = n;
*p->pos++ = n >> 8;
}
int
rb16(Pkt *p)
{
int n;
if(p->end - p->pos < 2){
fprint(2, "rb16() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 2);
longjmp(p->err, 1);
}
n = (*p->pos++) << 8;
n |= *p->pos++;
return n;
}
void
wb16(Pkt *p, int n)
{
if(p->end - p->pos < 2){
fprint(2, "wb16() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 2);
longjmp(p->err, 1);
}
*p->pos++ = n >> 8;
*p->pos++ = n;
}
int
rl32(Pkt *p)
{
int n;
if(p->end - p->pos < 4){
fprint(2, "rl32() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 4);
longjmp(p->err, 1);
}
n = *p->pos++;
n |= (*p->pos++) << 8;
n |= (*p->pos++) << 16;
n |= (*p->pos++) << 24;
return n;
}
void
wl32(Pkt *p, int n)
{
if(p->end - p->pos < 4){
fprint(2, "wl32() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 4);
longjmp(p->err, 1);
}
*p->pos++ = n;
*p->pos++ = n >> 8;
*p->pos++ = n >> 16;
*p->pos++ = n >> 24;
}
int
rb32(Pkt *p)
{
int n;
if(p->end - p->pos < 4){
fprint(2, "rb32() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 4);
longjmp(p->err, 1);
}
n = (*p->pos++) << 24;
n |= (*p->pos++) << 16;
n |= (*p->pos++) << 8;
n |= *p->pos++;
return n;
}
void
wb32(Pkt *p, int n)
{
if(p->end - p->pos < 4){
fprint(2, "rb32() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 4);
longjmp(p->err, 1);
}
*p->pos++ = n >> 24;
*p->pos++ = n >> 16;
*p->pos++ = n >> 8;
*p->pos++ = n;
}
void
skip(Pkt *p, int len)
{
if(p->end - p->pos < len){
fprint(2, "skip() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, len);
longjmp(p->err, 1);
}
p->pos += len;
}
void
rmem(Pkt *p, void *buf, int len)
{
if(p->end - p->pos < len){
fprint(2, "rmem() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, len);
longjmp(p->err, 1);
}
memcpy(buf, p->pos, len);
p->pos += len;
}
void
wmem(Pkt *p, void *buf, int len)
{
if(p->end - p->pos < len){
fprint(2, "wmem() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, len);
longjmp(p->err, 1);
}
memcpy(p->pos, buf, len);
p->pos += len;
}
void
rstr(Pkt *p, char *buf, int len)
{
int i;
if(p->end - p->pos < 1){
fprint(2, "rstr() unexpected end of packet (%uld<%d)\n",
p->end - p->pos, 1);
longjmp(p->err, 1);
}
for(i = 0; i < len; i++)
if((buf[i] = r8(p)) == 0)
break;
buf[len-1] = 0;
}
void
wstr(Pkt *p, char *buf)
{
while(*buf)
w8(p, *buf++);
w8(p, 0);
}
int
rnbname(Pkt *p, char *buf, int len)
{
int i, type;
type = *p->pos++;
for(i = 0; i < len && p->end - p->pos > 3; i++){
buf[i] = ((*p->pos++ - 'A') << 4) & 0xff;
buf[i] |= *p->pos++ - 'A';
if(*p->pos == 0){
p->pos++;
i++;
break;
}
}
buf[i] = 0;
return type;
}
void
pnbname(Pkt *p, char *name, char type, char pad)
{
char c;
int i;
int done = 0;
*(p->pos++) = 0x20;
for(i = 0; i < 15; i++) {
if(!done && name[i] == '\0')
done = 1;
if(done)
c = pad;
else
c = toupper(name[i]);
*(p->pos++) = (c >> 4) + 'A';
*(p->pos++) = (c & 0xf) + 'A';
}
*(p->pos++) = (type >> 4) + 'A';
*(p->pos++) = (type & 0xf) + 'A';
*(p->pos++) = 0x0;
}
|