static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len) { int status; u32 val; val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ | (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) | I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK; writel(val, i2cd->regs + I2C_MST_CNTL); status = gpu_i2c_check_status(i2cd); if (status < 0) return status; val = readl(i2cd->regs + I2C_MST_DATA); switch (len) { case 1: data[0] = val; break; case 2: put_unaligned_be16(val, data); break; case 3: put_unaligned_be16(val >> 8, data); data[2] = val; break; case 4: put_unaligned_be32(val, data); break; default: break; } return status; }
/** * Pack values defined by a type string into a buffer. The buffer must have * large enough space. * * @param type_str type string * @param values text strings of values to be packed * @param data output buffer of values * @return 0 on success, non-0 on error */ static int type_string_pack(const char *type_str, char * const values[], uint8_t *data) { size_t offset; uint32_t value; for (offset = 0; *type_str; type_str++, values++) { value = simple_strtoul(values[0], NULL, 0); switch (*type_str) { case 'b': data[offset] = value; offset += 1; break; case 'w': put_unaligned_be16(value, data + offset); offset += 2; break; case 'd': put_unaligned_be32(value, data + offset); offset += 4; break; default: return -1; } } return 0; }
static int sigmadsp_read_i2c(void *control_data, unsigned int addr, uint8_t data[], size_t len) { struct i2c_client *client = control_data; struct i2c_msg msgs[2]; uint8_t buf[2]; int ret; put_unaligned_be16(addr, buf); msgs[0].addr = client->addr; msgs[0].len = sizeof(buf); msgs[0].buf = buf; msgs[0].flags = 0; msgs[1].addr = client->addr; msgs[1].len = len; msgs[1].buf = data; msgs[1].flags = I2C_M_RD; ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (ret < 0) return ret; else if (ret != ARRAY_SIZE(msgs)) return -EIO; return 0; }
static int pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn) { unsigned char cdb[MAX_COMMAND_SIZE], *buf; int ret; buf = kzalloc(INQUIRY_VPD_SERIAL_LEN, GFP_KERNEL); if (!buf) return -ENOMEM; memset(cdb, 0, MAX_COMMAND_SIZE); cdb[0] = INQUIRY; cdb[1] = 0x01; /* Query VPD */ cdb[2] = 0x80; /* Unit Serial Number */ put_unaligned_be16(INQUIRY_VPD_SERIAL_LEN, &cdb[3]); ret = scsi_execute_req(sdev, cdb, DMA_FROM_DEVICE, buf, INQUIRY_VPD_SERIAL_LEN, NULL, HZ, 1, NULL); if (ret) goto out_free; snprintf(&wwn->unit_serial[0], INQUIRY_VPD_SERIAL_LEN, "%s", &buf[4]); wwn->t10_dev->dev_flags |= DF_FIRMWARE_VPD_UNIT_SERIAL; kfree(buf); return 0; out_free: kfree(buf); return -EPERM; }
/* * submit_stpg - Issue a SET TARGET GROUP STATES command * * Currently we're only setting the current target port group state * to 'active/optimized' and let the array firmware figure out * the states of the remaining groups. */ static unsigned submit_stpg(struct alua_dh_data *h) { struct request *rq; int stpg_len = 8; struct scsi_device *sdev = h->sdev; /* Prepare the data buffer */ memset(h->buff, 0, stpg_len); h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; put_unaligned_be16(h->group_id, &h->buff[6]); rq = get_alua_req(sdev, h->buff, stpg_len, WRITE); if (!rq) return SCSI_DH_RES_TEMP_UNAVAIL; /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_OUT; rq->cmd[1] = MO_SET_TARGET_PGS; put_unaligned_be32(stpg_len, &rq->cmd[6]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT); rq->sense = h->sense; memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); rq->sense_len = 0; rq->end_io_data = h; blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio); return SCSI_DH_OK; }
static void init_scalar_inquiry(struct lu_phy_attr *lu) { struct smc_priv *smc_p; smc_p = lu->lu_private; lu->inquiry[2] = 3; /* SNSI Approved Version */ lu->inquiry[3] = 2; /* Response data format */ lu->inquiry[4] = 0x1f; /* Additional length */ lu->inquiry[6] |= smc_p->pm->library_has_barcode_reader ? 0x20 : 0; lu->inquiry[55] |= smc_p->pm->library_has_barcode_reader ? 1 : 0; put_unaligned_be16(0x005c, &lu->inquiry[58]); /* SAM-2 */ put_unaligned_be16(0x008d, &lu->inquiry[60]); /* SAM-4 */ put_unaligned_be16(0x0120, &lu->inquiry[62]); /* SPC-3 */ put_unaligned_be16(0x02fe, &lu->inquiry[64]); /* SMC-2 */ }
bool config_parser_handle_guid(struct list_head *head, void *data) { struct ptoken *t, *first; unsigned char *target = data; union { unsigned tmp_ints[16]; struct { unsigned f[4]; unsigned long long l; } s; } x; unsigned i, *tmp_id = x.tmp_ints; first = list_entry(head->next, struct ptoken, list); t = config_token_after_equal(head); if(!t) { logg(LOGF_NOTICE, "Parsing config file %s@%zu: Option \"%s\" wants a value assigned, will ignore\n", first->ctx->in_filename, first->ctx->line_num, first->d.t); return true; } if(16 != sscanf(t->d.t, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", tmp_id, tmp_id+1, tmp_id+2, tmp_id+3, tmp_id+4, tmp_id+5, tmp_id+6, tmp_id+7, tmp_id+8, tmp_id+9, tmp_id+10, tmp_id+11, tmp_id+12, tmp_id+13, tmp_id+14, tmp_id+15)) { if(5 != sscanf(t->d.t, "%08X-%04X-%04X-%04X-%012" #ifndef WIN32 "llX", #else "I64X", #endif x.s.f, x.s.f+1, x.s.f+2, x.s.f+3, &x.s.l)) { logg(LOGF_NOTICE, "Parsing config file %s@%zu: \"%s\" does not seem to be a valid guid, will ignore\n", first->ctx->in_filename, first->ctx->line_num, t->d.t); return true; } else { /* * guids come from windows systems, their format * has a plattform endian touch (first 3 fields), * but that plattform is "always" intel... */ // TODO: GUIDs and enianess? put_unaligned_le32(x.s.f[0], target); put_unaligned_le16(x.s.f[1], target + 4); put_unaligned_le16(x.s.f[2], target + 6); put_unaligned_be16(x.s.f[3], target + 8); put_unaligned_be16(x.s.l >> 32, target + 10); put_unaligned_be32(x.s.l, target + 12); } } else { for(i = 0; i < 16; i++)
static void csum_ccitt(const u8 *buf, size_t size, u8 *crc) { const u16 calculated = crc_ccitt_false(0xffff, buf, size); /* * While the rest of the wire protocol is little-endian, * CCITT-16 CRC in RDU2 device is sent out in big-endian order. */ put_unaligned_be16(calculated, crc); }
/** * ad_sd_write_reg() - Write a register * * @sigma_delta: The sigma delta device * @reg: Address of the register * @size: Size of the register (0-3) * @val: Value to write to the register * * Returns 0 on success, an error code otherwise. **/ int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, unsigned int size, unsigned int val) { uint8_t *data = sigma_delta->data; struct spi_transfer t = { .tx_buf = data, .len = size + 1, .cs_change = sigma_delta->bus_locked, }; struct spi_message m; int ret; data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm; switch (size) { case 3: data[1] = val >> 16; data[2] = val >> 8; data[3] = val; break; case 2: put_unaligned_be16(val, &data[1]); break; case 1: data[1] = val; break; case 0: break; default: return -EINVAL; } spi_message_init(&m); spi_message_add_tail(&t, &m); if (sigma_delta->bus_locked) ret = spi_sync_locked(sigma_delta->spi, &m); else ret = spi_sync(sigma_delta->spi, &m); return ret; } EXPORT_SYMBOL_GPL(ad_sd_write_reg); static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, unsigned int reg, unsigned int size, uint8_t *val) { uint8_t *data = sigma_delta->data; int ret; struct spi_transfer t[] = { { .tx_buf = data, .len = 1, }, { .rx_buf = val,
int add_mode_device_configuration_extention(struct lu_phy_attr *lu) { struct list_head *mode_pg; struct priv_lu_ssc *ssc; struct ssc_personality_template *pm; struct mode *mp; uint8_t pcode; uint8_t subpcode; uint8_t size; /* Only for TAPE (SSC) devices */ if (lu->ptype != TYPE_TAPE) return -ENOTTY; ssc = lu->lu_private; pm = ssc->pm; mode_pg = &lu->mode_pg; pcode = MODE_DEVICE_CONFIGURATION; subpcode = 0x01; size = 32; MHVTL_DBG(3, "Adding mode page %s (%02x/%02x)", mode_device_configuration_extension, pcode, subpcode); mp = alloc_mode_page(mode_pg, pcode, subpcode, size); if (!mp) return -ENOMEM; mp->pcodePointer[0] = pcode; mp->pcodePointer[1] = size - sizeof(mp->pcodePointer[0]) - sizeof(mp->pcodePointer[1]); /* And copy pcode/size into bitmap structure */ mp->pcodePointerBitMap[0] = mp->pcodePointer[0]; mp->pcodePointerBitMap[1] = mp->pcodePointer[1]; mp->pcodePointer[5] = 0x02; /* Short erase mode - write EOD */ /* default size of early warning */ put_unaligned_be16(0, &mp->pcodePointer[6]); /* Update mode page bitmap to reflect changeable fields */ if (pm->drive_supports_append_only_mode) mp->pcodePointerBitMap[5] |= 0xf0; if (pm->drive_supports_prog_early_warning) { mp->pcodePointerBitMap[6] |= 0xff; mp->pcodePointerBitMap[7] |= 0xff; } mp->description = mode_device_configuration_extension; return 0; }
/* * si470x_set_register - write register */ int si470x_set_register(struct si470x_device *radio, int regnr) { int retval; radio->usb_buf[0] = REGISTER_REPORT(regnr); put_unaligned_be16(radio->registers[regnr], &radio->usb_buf[1]); retval = si470x_set_report(radio, radio->usb_buf, REGISTER_REPORT_SIZE); return (retval < 0) ? -EINVAL : 0; }
/* * si470x_set_register - write register */ static int si470x_set_register(struct si470x_device *radio, int regnr) { unsigned char buf[REGISTER_REPORT_SIZE]; int retval; buf[0] = REGISTER_REPORT(regnr); put_unaligned_be16(radio->registers[regnr], &buf[1]); retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); return (retval < 0) ? -EINVAL : 0; }
static int ssc_read_block_limit(int host_no, struct scsi_cmd *cmd) { uint8_t buf[READ_BLK_LIMITS_SZ]; uint8_t block_length = ssc_get_block_length(cmd->dev); memset(buf, 0, sizeof(buf)); buf[0] = GRANULARITY; if (block_length) { /* Fixed block size */ put_unaligned_be24(block_length, buf + 1); put_unaligned_be16(block_length, buf + 4); } else { /* Variable block size */ put_unaligned_be24(MAX_BLK_SIZE, buf + 1); put_unaligned_be16(MIN_BLK_SIZE, buf + 4); } memcpy(scsi_get_in_buffer(cmd), buf, READ_BLK_LIMITS_SZ); eprintf("In ssc_read_block_limit \n"); return SAM_STAT_GOOD; }
/** * scsi_set_sense_field_pointer - set the field pointer sense key * specific information in a formatted sense data buffer * @buf: Where to build sense data * @buf_len: buffer length * @fp: field pointer to be set * @bp: bit pointer to be set * @cd: command/data bit * * Return value: * 0 on success or EINVAL for invalid sense buffer length */ int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd) { u8 *ucp, len; if ((buf[0] & 0x7f) == 0x72) { len = buf[7]; ucp = (char *)scsi_sense_desc_find(buf, len + 8, 2); if (!ucp) { buf[7] = len + 8; ucp = buf + 8 + len; } if (buf_len < len + 8) /* Not enough room for info */ return -EINVAL; ucp[0] = 2; ucp[1] = 6; ucp[4] = 0x80; /* Valid bit */ if (cd) ucp[4] |= 0x40; if (bp < 0x8) ucp[4] |= 0x8 | bp; put_unaligned_be16(fp, &ucp[5]); } else if ((buf[0] & 0x7f) == 0x70) { len = buf[7]; if (len < 18) buf[7] = 18; buf[15] = 0x80; if (cd) buf[15] |= 0x40; if (bp < 0x8) buf[15] |= 0x8 | bp; put_unaligned_be16(fp, &buf[16]); } return 0; }
static void skd_prep_discard_cdb(struct skd_scsi_request *scsi_req, struct skd_request_context *skreq, struct page *page, u32 lba, u32 count) { char *buf; unsigned long len; struct request *req; buf = page_address(page); len = SKD_DISCARD_CDB_LENGTH; scsi_req->cdb[0] = UNMAP; scsi_req->cdb[8] = len; put_unaligned_be16(6 + 16, &buf[0]); put_unaligned_be16(16, &buf[2]); put_unaligned_be64(lba, &buf[8]); put_unaligned_be32(count, &buf[16]); req = skreq->req; blk_add_request_payload(req, page, len); }
int add_mode_element_address_assignment(struct lu_phy_attr *lu) { struct list_head *mode_pg; struct mode *mp; static struct smc_priv *smc_slots; uint8_t pcode; uint8_t subpcode; uint8_t size; uint8_t *p; mode_pg = &lu->mode_pg; smc_slots = (struct smc_priv *)lu->lu_private; pcode = MODE_ELEMENT_ADDRESS; subpcode = 0; size = 20; MHVTL_DBG(3, "Adding mode page %s (%02x/%02x)", mode_element_address, pcode, subpcode); mp = alloc_mode_page(mode_pg, pcode, subpcode, size); if (!mp) return -ENOMEM; p = mp->pcodePointer; p[0] = pcode; p[1] = size - sizeof(p[0]) - sizeof(p[1]); /* And copy pcode/size into bitmap structure */ mp->pcodePointerBitMap[0] = mp->pcodePointer[0]; mp->pcodePointerBitMap[1] = mp->pcodePointer[1]; put_unaligned_be16(START_PICKER, &p[2]); /* First transport. */ put_unaligned_be16(smc_slots->num_picker, &p[4]); put_unaligned_be16(START_STORAGE, &p[6]); /* First storage */ put_unaligned_be16(smc_slots->num_storage, &p[8]); put_unaligned_be16(START_MAP, &p[10]); /* First i/e address */ put_unaligned_be16(smc_slots->num_map, &p[12]); put_unaligned_be16(START_DRIVE, &p[14]); /* First Drives */ put_unaligned_be16(smc_slots->num_drives, &p[16]); mp->description = mode_element_address; return 0; }
/* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet * Detection is supported through ethtool */ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); u32 reg; wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE; wol->wolopts = priv->wolopts; memset(wol->sopass, 0, sizeof(wol->sopass)); if (wol->wolopts & WAKE_MAGICSECURE) { reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_MS); put_unaligned_be16(reg, &wol->sopass[0]); reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_LS); put_unaligned_be32(reg, &wol->sopass[2]); } }
static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag, uint32_t len) { *buf++ = tag; if (len <= 127) { buf[0] = len; return buf + 1; } if (len <= 255) { buf[0] = 0x81; buf[1] = len; return buf + 2; } buf[0] = 0x82; put_unaligned_be16(len, buf + 1); return buf + 3; }
int update_prog_early_warning(struct lu_phy_attr *lu) { uint8_t *mp; struct mode *m; struct list_head *mode_pg; struct priv_lu_ssc *lu_priv; mode_pg = &lu->mode_pg; lu_priv = (struct priv_lu_ssc *)lu->lu_private; m = lookup_pcode(mode_pg, MODE_DEVICE_CONFIGURATION, 1); MHVTL_DBG(3, "l: %p, m: %p, m->pcodePointer: %p", mode_pg, m, m->pcodePointer); if (m) { mp = m->pcodePointer; if (!mp) return SAM_STAT_GOOD; put_unaligned_be16(lu_priv->prog_early_warning_sz, &mp[6]); } return SAM_STAT_GOOD; }
static int sigmadsp_write_i2c(void *control_data, unsigned int addr, const uint8_t data[], size_t len) { uint8_t *buf; int ret; buf = kzalloc(2 + len, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; put_unaligned_be16(addr, buf); memcpy(buf + 2, data, len); ret = i2c_master_send(control_data, buf, len + 2); kfree(buf); if (ret < 0) return ret; return 0; }
/* * saddr == NULL means use device source address. * daddr == NULL means leave destination address (eg unresolved arp). */ static int fwnet_header_create(struct sk_buff *skb, struct net_device *net, unsigned short type, const void *daddr, const void *saddr, unsigned len) { struct fwnet_header *h; h = (struct fwnet_header *)skb_push(skb, sizeof(*h)); put_unaligned_be16(type, &h->h_proto); if (net->flags & (IFF_LOOPBACK | IFF_NOARP)) { memset(h->h_dest, 0, net->addr_len); return net->hard_header_len; } if (daddr) { memcpy(h->h_dest, daddr, net->addr_len); return net->hard_header_len; } return -net->hard_header_len; }
static int encr_capabilities_ult(struct scsi_cmd *cmd) { uint8_t *buf = cmd->dbuf_p->data; struct priv_lu_ssc *lu_priv = cmd->lu->lu_private; put_unaligned_be16(ENCR_CAPABILITIES, &buf[0]); put_unaligned_be16(40, &buf[2]); /* List length */ buf[20] = 1; /* Algorithm index */ buf[21] = 0; /* Reserved */ put_unaligned_be16(0x14, &buf[22]); /* Descriptor length */ buf[24] = 0x3a; /* MAC C/DED_C DECRYPT_C = 2 ENCRYPT_C = 2 */ buf[25] = 0x10; /* NONCE_C = 1 */ /* Max unauthenticated key data */ put_unaligned_be16(0x20, &buf[26]); /* Max authenticated key data */ put_unaligned_be16(0x0c, &buf[28]); /* Key size */ put_unaligned_be16(0x20, &buf[30]); buf[32] = 0x01; /* EAREM */ /* buf 12 - 19 reserved */ buf[40] = 0; /* Encryption Algorithm Id */ buf[41] = 0x01; /* Encryption Algorithm Id */ buf[42] = 0; /* Encryption Algorithm Id */ buf[43] = 0x14; /* Encryption Algorithm Id */ /* adjustments for each emulated drive type */ buf[4] = 0x1; /* CFG_P == 01b */ if (lu_priv->tapeLoaded == TAPE_LOADED) { switch (mam.MediaType) { case Media_LTO4: MHVTL_DBG(1, "LTO4 Medium"); buf[24] |= 0x80; /* AVFMV */ break; case Media_LTO5: MHVTL_DBG(1, "LTO5 Medium"); buf[24] |= 0x80; /* AVFMV */ break; } } buf[32] |= 0x08; /* RDMC_C == 4 */ return 44; }
static int encr_capabilities_t10k(struct scsi_cmd *cmd) { uint8_t *buf = cmd->dbuf_p->data; struct priv_lu_ssc *lu_priv = cmd->lu->lu_private; MHVTL_DBG(3, "+++ Trace +++"); put_unaligned_be16(ENCR_CAPABILITIES, &buf[0]); put_unaligned_be16(40, &buf[2]); /* List length */ buf[20] = 1; /* Algorithm index */ buf[21] = 0; /* Reserved */ put_unaligned_be16(0x14, &buf[22]); /* Descriptor length */ buf[24] = 0x3a; /* MAC C/DED_C DECRYPT_C = 2 ENCRYPT_C = 2 */ buf[25] = 0x10; /* NONCE_C = 1 */ /* Max unauthenticated key data */ put_unaligned_be16(0x20, &buf[26]); /* Max authenticated key data */ put_unaligned_be16(0x0c, &buf[28]); /* Key size */ put_unaligned_be16(0x20, &buf[30]); buf[32] = 0x01; /* EAREM */ /* buf 12 - 19 reserved */ buf[40] = 0; /* Encryption Algorithm Id */ buf[41] = 0x01; /* Encryption Algorithm Id */ buf[42] = 0; /* Encryption Algorithm Id */ buf[43] = 0x14; /* Encryption Algorithm Id */ buf[4] = 0x1; /* CFG_P == 01b */ if (lu_priv->tapeLoaded == TAPE_LOADED) { buf[24] |= 0x80; /* AVFMV */ buf[27] = 0x1e; /* Max unauthenticated key data */ buf[29] = 0x00; /* Max authenticated key data */ buf[32] |= 0x42; /* DKAD_C == 1, RDMC_C == 1 */ buf[40] = 0x80; /* Encryption Algorithm Id */ buf[43] = 0x10; /* Encryption Algorithm Id */ } return 44; }
static int encr_capabilities_3592(struct scsi_cmd *cmd) { uint8_t *buf = cmd->dbuf_p->data; struct priv_lu_ssc *lu_priv = cmd->lu->lu_private; put_unaligned_be16(ENCR_CAPABILITIES, &buf[0]); put_unaligned_be16(40, &buf[2]); /* List length */ buf[20] = 1; /* Algorithm index */ buf[21] = 0; /* Reserved */ put_unaligned_be16(0x14, &buf[22]); /* Descriptor length */ buf[24] = 0x3a; /* MAC C/DED_C DECRYPT_C = 2 ENCRYPT_C = 2 */ buf[25] = 0x10; /* NONCE_C = 1 */ /* Max unauthenticated key data */ put_unaligned_be16(0x20, &buf[26]); /* Max authenticated key data */ put_unaligned_be16(0x0c, &buf[28]); /* Key size */ put_unaligned_be16(0x20, &buf[30]); buf[32] = 0x01; /* EAREM */ /* buf 12 - 19 reserved */ buf[40] = 0; /* Encryption Algorithm Id */ buf[41] = 0x01; /* Encryption Algorithm Id */ buf[42] = 0; /* Encryption Algorithm Id */ buf[43] = 0x14; /* Encryption Algorithm Id */ /* MHVTL_DBG(1, "Drive type: %s, Media type: %s", drive_name(lunit.drive_type), lookup_media_type(mam.MediaType)); */ if (lu_priv->tapeLoaded == TAPE_LOADED) { buf[24] |= 0x80; /* AVFMV */ buf[27] = 0x00; /* Max unauthenticated key data */ buf[32] |= 0x0e; /* RDMC_C == 7 */ } return 44; }
static int iscsi_get_pr_transport_id( struct se_node_acl *se_nacl, struct t10_pr_registration *pr_reg, int *format_code, unsigned char *buf) { u32 off = 4, padding = 0; u16 len = 0; spin_lock_irq(&se_nacl->nacl_sess_lock); /* * From spc4r17 Section 7.5.4.6: TransportID for initiator * ports using SCSI over iSCSI. * * The null-terminated, null-padded (see 4.4.2) ISCSI NAME field * shall contain the iSCSI name of an iSCSI initiator node (see * RFC 3720). The first ISCSI NAME field byte containing an ASCII * null character terminates the ISCSI NAME field without regard for * the specified length of the iSCSI TransportID or the contents of * the ADDITIONAL LENGTH field. */ len = sprintf(&buf[off], "%s", se_nacl->initiatorname); /* * Add Extra byte for NULL terminator */ len++; /* * If there is ISID present with the registration and *format code == 1 * 1, use iSCSI Initiator port TransportID format. * * Otherwise use iSCSI Initiator device TransportID format that * does not contain the ASCII encoded iSCSI Initiator iSID value * provied by the iSCSi Initiator during the iSCSI login process. */ if ((*format_code == 1) && (pr_reg->isid_present_at_reg)) { /* * Set FORMAT CODE 01b for iSCSI Initiator port TransportID * format. */ buf[0] |= 0x40; /* * From spc4r17 Section 7.5.4.6: TransportID for initiator * ports using SCSI over iSCSI. Table 390 * * The SEPARATOR field shall contain the five ASCII * characters ",i,0x". * * The null-terminated, null-padded ISCSI INITIATOR SESSION ID * field shall contain the iSCSI initiator session identifier * (see RFC 3720) in the form of ASCII characters that are the * hexadecimal digits converted from the binary iSCSI initiator * session identifier value. The first ISCSI INITIATOR SESSION * ID field byte containing an ASCII null character */ buf[off+len] = 0x2c; off++; /* ASCII Character: "," */ buf[off+len] = 0x69; off++; /* ASCII Character: "i" */ buf[off+len] = 0x2c; off++; /* ASCII Character: "," */ buf[off+len] = 0x30; off++; /* ASCII Character: "0" */ buf[off+len] = 0x78; off++; /* ASCII Character: "x" */ len += 5; buf[off+len] = pr_reg->pr_reg_isid[0]; off++; buf[off+len] = pr_reg->pr_reg_isid[1]; off++; buf[off+len] = pr_reg->pr_reg_isid[2]; off++; buf[off+len] = pr_reg->pr_reg_isid[3]; off++; buf[off+len] = pr_reg->pr_reg_isid[4]; off++; buf[off+len] = pr_reg->pr_reg_isid[5]; off++; buf[off+len] = '\0'; off++; len += 7; } spin_unlock_irq(&se_nacl->nacl_sess_lock); /* * The ADDITIONAL LENGTH field specifies the number of bytes that follow * in the TransportID. The additional length shall be at least 20 and * shall be a multiple of four. */ padding = ((-len) & 3); if (padding != 0) len += padding; put_unaligned_be16(len, &buf[2]); /* * Increment value for total payload + header length for * full status descriptor */ len += 4; return len; }
static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, int encrypted) { __le16 mask_fc; int a4_included; u8 qos_tid; u8 *b_0, *aad; u16 data_len, len_a; unsigned int hdrlen; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; b_0 = scratch + 3 * AES_BLOCK_LEN; aad = scratch + 4 * AES_BLOCK_LEN; /* * Mask FC: zero subtype b4 b5 b6 * Retry, PwrMgt, MoreData; set Protected */ mask_fc = hdr->frame_control; mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); hdrlen = ieee80211_hdrlen(hdr->frame_control); len_a = hdrlen - 2; a4_included = ieee80211_has_a4(hdr->frame_control); if (ieee80211_is_data_qos(hdr->frame_control)) qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; else qos_tid = 0; data_len = skb->len - hdrlen - CCMP_HDR_LEN; if (encrypted) data_len -= CCMP_MIC_LEN; /* First block, b_0 */ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ /* Nonce: QoS Priority | A2 | PN */ b_0[1] = qos_tid; memcpy(&b_0[2], hdr->addr2, ETH_ALEN); memcpy(&b_0[8], pn, CCMP_PN_LEN); /* l(m) */ put_unaligned_be16(data_len, &b_0[14]); /* AAD (extra authenticate-only data) / masked 802.11 header * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ put_unaligned_be16(len_a, &aad[0]); put_unaligned(mask_fc, (__le16 *)&aad[2]); memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); /* Mask Seq#, leave Frag# */ aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; aad[23] = 0; if (a4_included) { memcpy(&aad[24], hdr->addr4, ETH_ALEN); aad[30] = qos_tid; aad[31] = 0; } else { memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); aad[24] = qos_tid; } }
static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, unsigned count) { struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; struct redrat3_irdata *irdata = NULL; int ret, ret_len; int lencheck, cur_sample_len, pipe; int *sample_lens = NULL; u8 curlencheck = 0; unsigned i, sendbuf_len; rr3_ftr(dev, "Entering %s\n", __func__); if (rr3->transmitting) { dev_warn(dev, "%s: transmitter already in use\n", __func__); return -EAGAIN; } if (count > RR3_MAX_SIG_SIZE - RR3_TX_TRAILER_LEN) return -EINVAL; /* rr3 will disable rc detector on transmit */ rr3->transmitting = true; sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); if (!sample_lens) { ret = -ENOMEM; goto out; } irdata = kzalloc(sizeof(*irdata), GFP_KERNEL); if (!irdata) { ret = -ENOMEM; goto out; } for (i = 0; i < count; i++) { cur_sample_len = redrat3_us_to_len(txbuf[i]); if (cur_sample_len > 0xffff) { dev_warn(dev, "transmit period of %uus truncated to %uus\n", txbuf[i], redrat3_len_to_us(0xffff)); cur_sample_len = 0xffff; } for (lencheck = 0; lencheck < curlencheck; lencheck++) { if (sample_lens[lencheck] == cur_sample_len) break; } if (lencheck == curlencheck) { rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n", i, txbuf[i], curlencheck, cur_sample_len); if (curlencheck < RR3_DRIVER_MAXLENS) { /* now convert the value to a proper * rr3 value.. */ sample_lens[curlencheck] = cur_sample_len; put_unaligned_be16(cur_sample_len, &irdata->lens[curlencheck]); curlencheck++; } else { ret = -EINVAL; goto out; } } irdata->sigdata[i] = lencheck; } irdata->sigdata[count] = RR3_END_OF_SIGNAL; irdata->sigdata[count + 1] = RR3_END_OF_SIGNAL; sendbuf_len = offsetof(struct redrat3_irdata, sigdata[count + RR3_TX_TRAILER_LEN]); /* fill in our packet header */ irdata->header.length = cpu_to_be16(sendbuf_len - sizeof(struct redrat3_header)); irdata->header.transfer_type = cpu_to_be16(RR3_MOD_SIGNAL_OUT); irdata->pause = cpu_to_be32(redrat3_len_to_us(100)); irdata->mod_freq_count = cpu_to_be16(mod_freq_to_val(rr3->carrier)); irdata->no_lengths = curlencheck; irdata->sig_size = cpu_to_be16(count + RR3_TX_TRAILER_LEN); pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); ret = usb_bulk_msg(rr3->udev, pipe, irdata, sendbuf_len, &ret_len, 10 * HZ); rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret); /* now tell the hardware to transmit what we sent it */ pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0, 0, irdata, 2, HZ * 10); if (ret < 0) dev_err(dev, "Error: control msg send failed, rc %d\n", ret); else ret = count; out: kfree(sample_lens); kfree(irdata); rr3->transmitting = false; /* rr3 re-enables rc detector because it was enabled before */ return ret; }
/* * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3. * Well, not what's written there, but rather what they meant. */ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key) { struct scatterlist sg_in[1], sg_out[1]; struct blkcipher_desc desc = { .tfm = state->arc4 }; get_new_key_from_sha(state); if (!initial_key) { crypto_blkcipher_setkey(state->arc4, state->sha1_digest, state->keylen); sg_init_table(sg_in, 1); sg_init_table(sg_out, 1); setup_sg(sg_in, state->sha1_digest, state->keylen); setup_sg(sg_out, state->session_key, state->keylen); if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, state->keylen) != 0) { printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n"); } } else { memcpy(state->session_key, state->sha1_digest, state->keylen); } if (state->keylen == 8) { /* See RFC 3078 */ state->session_key[0] = 0xd1; state->session_key[1] = 0x26; state->session_key[2] = 0x9e; } crypto_blkcipher_setkey(state->arc4, state->session_key, state->keylen); } /* * Allocate space for a (de)compressor. */ static void *mppe_alloc(unsigned char *options, int optlen) { struct ppp_mppe_state *state; unsigned int digestsize; if (optlen != CILEN_MPPE + sizeof(state->master_key) || options[0] != CI_MPPE || options[1] != CILEN_MPPE) goto out; state = kzalloc(sizeof(*state), GFP_KERNEL); if (state == NULL) goto out; state->arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(state->arc4)) { state->arc4 = NULL; goto out_free; } state->sha1 = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(state->sha1)) { state->sha1 = NULL; goto out_free; } digestsize = crypto_hash_digestsize(state->sha1); if (digestsize < MPPE_MAX_KEY_LEN) goto out_free; state->sha1_digest = kmalloc(digestsize, GFP_KERNEL); if (!state->sha1_digest) goto out_free; /* Save keys. */ memcpy(state->master_key, &options[CILEN_MPPE], sizeof(state->master_key)); memcpy(state->session_key, state->master_key, sizeof(state->master_key)); /* * We defer initial key generation until mppe_init(), as mppe_alloc() * is called frequently during negotiation. */ return (void *)state; out_free: if (state->sha1_digest) kfree(state->sha1_digest); if (state->sha1) crypto_free_hash(state->sha1); if (state->arc4) crypto_free_blkcipher(state->arc4); kfree(state); out: return NULL; } /* * Deallocate space for a (de)compressor. */ static void mppe_free(void *arg) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; if (state) { if (state->sha1_digest) kfree(state->sha1_digest); if (state->sha1) crypto_free_hash(state->sha1); if (state->arc4) crypto_free_blkcipher(state->arc4); kfree(state); } } /* * Initialize (de)compressor state. */ static int mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug, const char *debugstr) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; unsigned char mppe_opts; if (optlen != CILEN_MPPE || options[0] != CI_MPPE || options[1] != CILEN_MPPE) return 0; MPPE_CI_TO_OPTS(&options[2], mppe_opts); if (mppe_opts & MPPE_OPT_128) state->keylen = 16; else if (mppe_opts & MPPE_OPT_40) state->keylen = 8; else { printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, unit); return 0; } if (mppe_opts & MPPE_OPT_STATEFUL) state->stateful = 1; /* Generate the initial session key. */ mppe_rekey(state, 1); if (debug) { int i; char mkey[sizeof(state->master_key) * 2 + 1]; char skey[sizeof(state->session_key) * 2 + 1]; printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr, unit, (state->keylen == 16) ? 128 : 40, (state->stateful) ? "stateful" : "stateless"); for (i = 0; i < sizeof(state->master_key); i++) sprintf(mkey + i * 2, "%02x", state->master_key[i]); for (i = 0; i < sizeof(state->session_key); i++) sprintf(skey + i * 2, "%02x", state->session_key[i]); printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n", debugstr, unit, mkey, skey); } /* * Initialize the coherency count. The initial value is not specified * in RFC 3078, but we can make a reasonable assumption that it will * start at 0. Setting it to the max here makes the comp/decomp code * do the right thing (determined through experiment). */ state->ccount = MPPE_CCOUNT_SPACE - 1; /* * Note that even though we have initialized the key table, we don't * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1. */ state->bits = MPPE_BIT_ENCRYPTED; state->unit = unit; state->debug = debug; return 1; } static int mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit, int hdrlen, int debug) { /* ARGSUSED */ return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init"); } /* * We received a CCP Reset-Request (actually, we are sending a Reset-Ack), * tell the compressor to rekey. Note that we MUST NOT rekey for * every CCP Reset-Request; we only rekey on the next xmit packet. * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost. * So, rekeying for every CCP Reset-Request is broken as the peer will not * know how many times we've rekeyed. (If we rekey and THEN get another * CCP Reset-Request, we must rekey again.) */ static void mppe_comp_reset(void *arg) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; state->bits |= MPPE_BIT_FLUSHED; } /* * Compress (encrypt) a packet. * It's strange to call this a compressor, since the output is always * MPPE_OVHD + 2 bytes larger than the input. */ static int mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, int isize, int osize) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; struct blkcipher_desc desc = { .tfm = state->arc4 }; int proto; struct scatterlist sg_in[1], sg_out[1]; /* * Check that the protocol is in the range we handle. */ proto = PPP_PROTOCOL(ibuf); if (proto < 0x0021 || proto > 0x00fa) return 0; /* Make sure we have enough room to generate an encrypted packet. */ if (osize < isize + MPPE_OVHD + 2) { /* Drop the packet if we should encrypt it, but can't. */ printk(KERN_DEBUG "mppe_compress[%d]: osize too small! " "(have: %d need: %d)\n", state->unit, osize, osize + MPPE_OVHD + 2); return -1; } osize = isize + MPPE_OVHD + 2; /* * Copy over the PPP header and set control bits. */ obuf[0] = PPP_ADDRESS(ibuf); obuf[1] = PPP_CONTROL(ibuf); put_unaligned_be16(PPP_COMP, obuf + 2); obuf += PPP_HDRLEN; state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; if (state->debug >= 7) printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit, state->ccount); put_unaligned_be16(state->ccount, obuf); if (!state->stateful || /* stateless mode */ ((state->ccount & 0xff) == 0xff) || /* "flag" packet */ (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */ /* We must rekey */ if (state->debug && state->stateful) printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit); mppe_rekey(state, 0); state->bits |= MPPE_BIT_FLUSHED; } obuf[0] |= state->bits; state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */ obuf += MPPE_OVHD; ibuf += 2; /* skip to proto field */ isize -= 2; /* Encrypt packet */ sg_init_table(sg_in, 1); sg_init_table(sg_out, 1); setup_sg(sg_in, ibuf, isize); setup_sg(sg_out, obuf, osize); if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, isize) != 0) { printk(KERN_DEBUG "crypto_cypher_encrypt failed\n"); return -1; } state->stats.unc_bytes += isize; state->stats.unc_packets++; state->stats.comp_bytes += osize; state->stats.comp_packets++; return osize; } /* * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going * to look bad ... and the longer the link is up the worse it will get. */ static void mppe_comp_stats(void *arg, struct compstat *stats) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; *stats = state->stats; } static int mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit, int hdrlen, int mru, int debug) { /* ARGSUSED */ return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init"); } /* * We received a CCP Reset-Ack. Just ignore it. */ static void mppe_decomp_reset(void *arg) { /* ARGSUSED */ return; } /* * Decompress (decrypt) an MPPE packet. */ static int mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf, int osize) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; struct blkcipher_desc desc = { .tfm = state->arc4 }; unsigned ccount; int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED; int sanity = 0; struct scatterlist sg_in[1], sg_out[1]; if (isize <= PPP_HDRLEN + MPPE_OVHD) { if (state->debug) printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n", state->unit, isize); return DECOMP_ERROR; } /* * Make sure we have enough room to decrypt the packet. * Note that for our test we only subtract 1 byte whereas in * mppe_compress() we added 2 bytes (+MPPE_OVHD); * this is to account for possible PFC. */ if (osize < isize - MPPE_OVHD - 1) { printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! " "(have: %d need: %d)\n", state->unit, osize, isize - MPPE_OVHD - 1); return DECOMP_ERROR; } osize = isize - MPPE_OVHD - 2; /* assume no PFC */ ccount = MPPE_CCOUNT(ibuf); if (state->debug >= 7) printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit, ccount); /* sanity checks -- terminate with extreme prejudice */ if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) { printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n", state->unit); state->sanity_errors += 100; sanity = 1; } if (!state->stateful && !flushed) { printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in " "stateless mode!\n", state->unit); state->sanity_errors += 100; sanity = 1; } if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) { printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on " "flag packet!\n", state->unit); state->sanity_errors += 100; sanity = 1; } if (sanity) { if (state->sanity_errors < SANITY_MAX) return DECOMP_ERROR; else /* * Take LCP down if the peer is sending too many bogons. * We don't want to do this for a single or just a few * instances since it could just be due to packet corruption. */ return DECOMP_FATALERROR; } /* * Check the coherency count. */ if (!state->stateful) { /* RFC 3078, sec 8.1. Rekey for every packet. */ while (state->ccount != ccount) { mppe_rekey(state, 0); state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; } } else { /* RFC 3078, sec 8.2. */ if (!state->discard) { /* normal state */ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; if (ccount != state->ccount) { /* * (ccount > state->ccount) * Packet loss detected, enter the discard state. * Signal the peer to rekey (by sending a CCP Reset-Request). */ state->discard = 1; return DECOMP_ERROR; } } else { /* discard state */ if (!flushed) { /* ccp.c will be silent (no additional CCP Reset-Requests). */ return DECOMP_ERROR; } else { /* Rekey for every missed "flag" packet. */ while ((ccount & ~0xff) != (state->ccount & ~0xff)) { mppe_rekey(state, 0); state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE; } /* reset */ state->discard = 0; state->ccount = ccount; /* * Another problem with RFC 3078 here. It implies that the * peer need not send a Reset-Ack packet. But RFC 1962 * requires it. Hopefully, M$ does send a Reset-Ack; even * though it isn't required for MPPE synchronization, it is * required to reset CCP state. */ } } if (flushed) mppe_rekey(state, 0); } /* * Fill in the first part of the PPP header. The protocol field * comes from the decrypted data. */ obuf[0] = PPP_ADDRESS(ibuf); /* +1 */ obuf[1] = PPP_CONTROL(ibuf); /* +1 */ obuf += 2; ibuf += PPP_HDRLEN + MPPE_OVHD; isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */ /* net osize: isize-4 */ /* * Decrypt the first byte in order to check if it is * a compressed or uncompressed protocol field. */ sg_init_table(sg_in, 1); sg_init_table(sg_out, 1); setup_sg(sg_in, ibuf, 1); setup_sg(sg_out, obuf, 1); if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, 1) != 0) { printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); return DECOMP_ERROR; } /* * Do PFC decompression. * This would be nicer if we were given the actual sk_buff * instead of a char *. */ if ((obuf[0] & 0x01) != 0) { obuf[1] = obuf[0]; obuf[0] = 0; obuf++; osize++; } /* And finally, decrypt the rest of the packet. */ setup_sg(sg_in, ibuf + 1, isize - 1); setup_sg(sg_out, obuf + 1, osize - 1); if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, isize - 1)) { printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); return DECOMP_ERROR; } state->stats.unc_bytes += osize; state->stats.unc_packets++; state->stats.comp_bytes += isize; state->stats.comp_packets++; /* good packet credit */ state->sanity_errors >>= 1; return osize; } /* * Incompressible data has arrived (this should never happen!). * We should probably drop the link if the protocol is in the range * of what should be encrypted. At the least, we should drop this * packet. (How to do this?) */ static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt) { struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; if (state->debug && (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa)) printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! " "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf)); state->stats.inc_bytes += icnt; state->stats.inc_packets++; state->stats.unc_bytes += icnt; state->stats.unc_packets++; } /************************************************************* * Module interface table *************************************************************/ /* * Procedures exported to if_ppp.c. */ static struct compressor ppp_mppe = { .compress_proto = CI_MPPE, .comp_alloc = mppe_alloc, .comp_free = mppe_free, .comp_init = mppe_comp_init, .comp_reset = mppe_comp_reset, .compress = mppe_compress, .comp_stat = mppe_comp_stats, .decomp_alloc = mppe_alloc, .decomp_free = mppe_free, .decomp_init = mppe_decomp_init, .decomp_reset = mppe_decomp_reset, .decompress = mppe_decompress, .incomp = mppe_incomp, .decomp_stat = mppe_comp_stats, .owner = THIS_MODULE, .comp_extra = MPPE_PAD, }; /* * ppp_mppe_init() * * Prior to allowing load, try to load the arc4 and sha1 crypto * libraries. The actual use will be allocated later, but * this way the module will fail to insmod if they aren't available. */ static int __init ppp_mppe_init(void) { int answer; if (!(crypto_has_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC) && crypto_has_hash("sha1", 0, CRYPTO_ALG_ASYNC))) return -ENODEV; sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL); if (!sha_pad) return -ENOMEM; sha_pad_init(sha_pad); answer = ppp_register_compressor(&ppp_mppe); if (answer == 0) printk(KERN_INFO "PPP MPPE Compression module registered\n"); else kfree(sha_pad); return answer; } static void __exit ppp_mppe_cleanup(void) { ppp_unregister_compressor(&ppp_mppe); kfree(sha_pad); } module_init(ppp_mppe_init); module_exit(ppp_mppe_cleanup);
static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, int isize, int osize) { struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; int r, proto, off, olen, oavail; unsigned char *wptr; /* */ proto = PPP_PROTOCOL(rptr); if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return 0; /* */ if (osize > isize) osize = isize; wptr = obuf; /* */ wptr[0] = PPP_ADDRESS(rptr); wptr[1] = PPP_CONTROL(rptr); put_unaligned_be16(PPP_COMP, wptr + 2); wptr += PPP_HDRLEN; put_unaligned_be16(state->seqno, wptr); wptr += DEFLATE_OVHD; olen = PPP_HDRLEN + DEFLATE_OVHD; state->strm.next_out = wptr; state->strm.avail_out = oavail = osize - olen; ++state->seqno; off = (proto > 0xff) ? 2 : 3; /* */ rptr += off; state->strm.next_in = rptr; state->strm.avail_in = (isize - off); for (;;) { r = zlib_deflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { if (state->debug) printk(KERN_ERR "z_compress: deflate returned %d\n", r); break; } if (state->strm.avail_out == 0) { olen += oavail; state->strm.next_out = NULL; state->strm.avail_out = oavail = 1000000; } else { break; /* */ } } olen += oavail - state->strm.avail_out; /* */ if (olen < isize) { state->stats.comp_bytes += olen; state->stats.comp_packets++; } else { state->stats.inc_bytes += isize; state->stats.inc_packets++; olen = 0; } state->stats.unc_bytes += isize; state->stats.unc_packets++; return olen; }
/** * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer * @inode: struct inode * * @file: struct file * * * Open function to open the /proc/dgrp/ports device for a PortServer. */ static int dgrp_mon_open(struct inode *inode, struct file *file) { struct nd_struct *nd; struct proc_dir_entry *de; struct timeval tv; uint32_t time; u8 *buf; int rtn; rtn = try_module_get(THIS_MODULE); if (!rtn) return -ENXIO; rtn = 0; if (!capable(CAP_SYS_ADMIN)) { rtn = -EPERM; goto done; } /* * Make sure that the "private_data" field hasn't already been used. */ if (file->private_data) { rtn = -EINVAL; goto done; } /* * Get the node pointer, and fail if it doesn't exist. */ de = PDE(inode); if (!de) { rtn = -ENXIO; goto done; } nd = (struct nd_struct *)de->data; if (!nd) { rtn = -ENXIO; goto done; } file->private_data = (void *) nd; /* * Allocate the monitor buffer. */ /* * Grab the MON lock. */ down(&nd->nd_mon_semaphore); if (nd->nd_mon_buf) { rtn = -EBUSY; goto done_up; } nd->nd_mon_buf = kmalloc(MON_MAX, GFP_KERNEL); if (!nd->nd_mon_buf) { rtn = -ENOMEM; goto done_up; } /* * Enter an RPDUMP file header into the buffer. */ buf = nd->nd_mon_buf; strcpy(buf, RPDUMP_MAGIC); buf += strlen(buf) + 1; do_gettimeofday(&tv); /* * tv.tv_sec might be a 64 bit quantity. Pare * it down to 32 bits before attempting to encode * it. */ time = (uint32_t) (tv.tv_sec & 0xffffffff); put_unaligned_be32(time, buf); put_unaligned_be16(0, buf + 4); buf += 6; if (nd->nd_tx_module) { buf[0] = RPDUMP_CLIENT; put_unaligned_be32(0, buf + 1); put_unaligned_be16(1, buf + 5); buf[7] = 0xf0 + nd->nd_tx_module; buf += 8; } if (nd->nd_rx_module) { buf[0] = RPDUMP_SERVER; put_unaligned_be32(0, buf + 1); put_unaligned_be16(1, buf + 5); buf[7] = 0xf0 + nd->nd_rx_module; buf += 8; } nd->nd_mon_out = 0; nd->nd_mon_in = buf - nd->nd_mon_buf; nd->nd_mon_lbolt = jiffies; done_up: up(&nd->nd_mon_semaphore); done: if (rtn) module_put(THIS_MODULE); return rtn; }